Merge "Add missing bindProgramRaster to scriptC_lib."
diff --git a/Android.mk b/Android.mk
index f7f752b..5eb5dda 100644
--- a/Android.mk
+++ b/Android.mk
@@ -192,7 +192,7 @@
$(framework-res-source-path)/com/android/internal/R.java
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core ext
+LOCAL_JAVA_LIBRARIES := core core-junit ext
LOCAL_MODULE := framework
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
@@ -431,7 +431,7 @@
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=2.1
+framework_docs_SDK_VERSION:=2.2
# release version (ie "Release x") (full releases only)
framework_docs_SDK_REL_ID:=1
# name of current SDK directory (full releases only)
@@ -440,10 +440,10 @@
framework_docs_SDK_PREVIEW:=0
## Latest ADT version identifiers, for reference from published docs
-framework_docs_ADT_VERSION:=0.9.6
-framework_docs_ADT_DOWNLOAD:=ADT-0.9.6.zip
-framework_docs_ADT_BYTES:=7456339
-framework_docs_ADT_CHECKSUM:=ea45d271be52b87b5dd1c9fb17536223
+framework_docs_ADT_VERSION:=0.9.7
+framework_docs_ADT_DOWNLOAD:=ADT-0.9.7.zip
+framework_docs_ADT_BYTES:=na
+framework_docs_ADT_CHECKSUM:=na
framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-hdf sdk.version $(framework_docs_SDK_VERSION) \
diff --git a/api/8.xml b/api/8.xml
index e757db2..9d259f3 100644
--- a/api/8.xml
+++ b/api/8.xml
@@ -80490,19 +80490,6 @@
<parameter name="volume" type="float">
</parameter>
</method>
-<method name="registerAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="registerMediaButtonEventReceiver"
return="void"
abstract="false"
@@ -80762,19 +80749,6 @@
visibility="public"
>
</method>
-<method name="unregisterAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="unregisterMediaButtonEventReceiver"
return="void"
abstract="false"
diff --git a/api/9.xml b/api/9.xml
index 256a388..cfa75a75 100644
--- a/api/9.xml
+++ b/api/9.xml
@@ -80435,19 +80435,6 @@
<parameter name="volume" type="float">
</parameter>
</method>
-<method name="registerAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="registerMediaButtonEventReceiver"
return="void"
abstract="false"
@@ -80707,19 +80694,6 @@
visibility="public"
>
</method>
-<method name="unregisterAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="unregisterMediaButtonEventReceiver"
return="void"
abstract="false"
diff --git a/api/current.xml b/api/current.xml
index 8f96f9e..1eaa6f4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3188,6 +3188,17 @@
visibility="public"
>
</field>
+<field name="customNavigationLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843539"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="cycles"
type="int"
transient="false"
@@ -3452,6 +3463,17 @@
visibility="public"
>
</field>
+<field name="displayOptions"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843537"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dither"
type="int"
transient="false"
@@ -6884,6 +6906,17 @@
visibility="public"
>
</field>
+<field name="navigationMode"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843536"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="negativeButtonText"
type="int"
transient="false"
@@ -8930,6 +8963,17 @@
visibility="public"
>
</field>
+<field name="subtitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843538"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="suggestActionMsg"
type="int"
transient="false"
@@ -10338,6 +10382,28 @@
visibility="public"
>
</field>
+<field name="windowActionBar"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843534"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="windowActionBarStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843535"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowAnimationStyle"
type="int"
transient="false"
@@ -14218,6 +14284,17 @@
visibility="public"
>
</field>
+<field name="home"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16908353"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="icon"
type="int"
transient="false"
@@ -16388,6 +16465,17 @@
visibility="public"
>
</field>
+<field name="Theme_WithActionBar"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973969"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget"
type="int"
transient="false"
@@ -19210,6 +19298,454 @@
</package>
<package name="android.app"
>
+<class name="ActionBar"
+ extends="java.lang.Object"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="ActionBar"
+ type="android.app.ActionBar"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getCustomNavigationView"
+ return="android.view.View"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDisplayOptions"
+ return="int"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNavigationMode"
+ return="int"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSubtitle"
+ return="java.lang.CharSequence"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTitle"
+ return="java.lang.CharSequence"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setBackgroundDrawable"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
+<method name="setCallback"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.app.ActionBar.Callback">
+</parameter>
+</method>
+<method name="setCustomNavigationView"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+</method>
+<method name="setDisplayOptions"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="options" type="int">
+</parameter>
+</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
+<method name="setNavigationMode"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
+<method name="setSubtitle"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="subtitle" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setTitle"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="title" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="updateActionMenu"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="DISPLAY_HIDE_HOME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DISPLAY_USE_LOGO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NAVIGATION_MODE_CUSTOM"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NAVIGATION_MODE_DROPDOWN_LIST"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NAVIGATION_MODE_NORMAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NAVIGATION_MODE_TABS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="ActionBar.Callback"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onActionItemSelected"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="item" type="android.view.MenuItem">
+</parameter>
+</method>
+<method name="onContextItemSelected"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="item" type="android.view.MenuItem">
+</parameter>
+</method>
+<method name="onCreateActionMenu"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onCreateContextMode"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onPrepareContextMode"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onUpdateActionMenu"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+</interface>
+<class name="ActionBar.SimpleCallback"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.app.ActionBar.Callback">
+</implements>
+<constructor name="ActionBar.SimpleCallback"
+ type="android.app.ActionBar.SimpleCallback"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="onActionItemSelected"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="item" type="android.view.MenuItem">
+</parameter>
+</method>
+<method name="onContextItemSelected"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="item" type="android.view.MenuItem">
+</parameter>
+</method>
+<method name="onCreateActionMenu"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onCreateContextMode"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onPrepareContextMode"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="modeId" type="int">
+</parameter>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+<method name="onUpdateActionMenu"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="menu" type="android.view.Menu">
+</parameter>
+</method>
+</class>
<class name="Activity"
extends="android.view.ContextThemeWrapper"
abstract="false"
@@ -19433,6 +19969,17 @@
<parameter name="child" type="android.app.Activity">
</parameter>
</method>
+<method name="getActionBar"
+ return="android.app.ActionBar"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getApplication"
return="android.app.Application"
abstract="false"
@@ -19677,6 +20224,17 @@
visibility="public"
>
</method>
+<method name="isChangingConfigurations"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="isChild"
return="boolean"
abstract="false"
@@ -63945,7 +64503,7 @@
<method name="drawText"
return="void"
abstract="false"
- native="true"
+ native="false"
synchronized="false"
static="false"
final="false"
@@ -85056,19 +85614,6 @@
<parameter name="volume" type="float">
</parameter>
</method>
-<method name="registerAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="registerMediaButtonEventReceiver"
return="void"
abstract="false"
@@ -85328,19 +85873,6 @@
visibility="public"
>
</method>
-<method name="unregisterAudioFocusListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="l" type="android.media.AudioManager.OnAudioFocusChangeListener">
-</parameter>
-</method>
<method name="unregisterMediaButtonEventReceiver"
return="void"
abstract="false"
@@ -147250,6 +147782,17 @@
visibility="public"
>
</field>
+<field name="NETWORK_TYPE_EVDO_B"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NETWORK_TYPE_GPRS"
type="int"
transient="false"
@@ -186761,6 +187304,19 @@
visibility="public"
>
</method>
+<method name="hasFeature"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="feature" type="int">
+</parameter>
+</method>
<method name="hasSoftInputMode"
return="boolean"
abstract="false"
@@ -187411,6 +187967,17 @@
visibility="protected"
>
</field>
+<field name="FEATURE_ACTION_BAR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FEATURE_CONTEXT_MENU"
type="int"
transient="false"
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index 41670af..cb69534 100644
--- a/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -298,6 +298,7 @@
virtual sp<OverlayRef> createOverlay(
uint32_t w, uint32_t h, int32_t format, int32_t orientation);
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
+ virtual status_t setBufferCount(int bufferCount);
// new functions
void clearStat();
@@ -339,6 +340,11 @@
return NULL;
}
+status_t MSurface::setBufferCount(int bufferCount) {
+ INFO(__func__);
+ return NULL;
+}
+
void MSurface::clearStat() {
Mutex::Autolock _l(mLock);
registerBuffersCount = 0;
diff --git a/common/java/com/android/common/GoogleLogTags.logtags b/common/java/com/android/common/GoogleLogTags.logtags
index a5c9bb0..f848ddf 100644
--- a/common/java/com/android/common/GoogleLogTags.logtags
+++ b/common/java/com/android/common/GoogleLogTags.logtags
@@ -80,7 +80,7 @@
204004 gtalk_heartbeat_reset (interval_and_nt|1),(ip|3)
# This event is logged when an Rmq v2 packet is sent or received.
-204005 push_messaging (packet_type|1),(persistent_id|3),(stream_id|1),(last_stream_id|1)
+204005 c2dm (packet_type|1),(persistent_id|3),(stream_id|1),(last_stream_id|1)
#####
# Google Login Service and Setup Wizard
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
new file mode 100644
index 0000000..e28d3d3
--- /dev/null
+++ b/core/java/android/app/ActionBar.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.graphics.drawable.Drawable;
+import android.view.ActionBarView;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * This is the public interface to the contextual ActionBar.
+ * The ActionBar acts as a replacement for the title bar in Activities.
+ * It provides facilities for creating toolbar actions as well as
+ * methods of navigating around an application.
+ */
+public abstract class ActionBar {
+ /**
+ * Normal/standard navigation mode. Consists of either a logo or icon
+ * and title text with an optional subtitle. Clicking any of these elements
+ * will dispatch onActionItemSelected to the registered Callback with
+ * a MenuItem with item ID android.R.id.home.
+ */
+ public static final int NAVIGATION_MODE_NORMAL = 0;
+
+ /**
+ * Dropdown list navigation mode. Instead of static title text this mode
+ * presents a dropdown menu for navigation within the activity.
+ */
+ public static final int NAVIGATION_MODE_DROPDOWN_LIST = 1;
+
+ /**
+ * Tab navigation mode. Instead of static title text this mode
+ * presents a series of tabs for navigation within the activity.
+ */
+ public static final int NAVIGATION_MODE_TABS = 2;
+
+ /**
+ * Custom navigation mode. This navigation mode is set implicitly whenever
+ * a custom navigation view is set. See {@link #setCustomNavigationView(View)}.
+ */
+ public static final int NAVIGATION_MODE_CUSTOM = 3;
+
+ /**
+ * Use logo instead of icon if available. This flag will cause appropriate
+ * navigation modes to use a wider logo in place of the standard icon.
+ */
+ public static final int DISPLAY_USE_LOGO = 0x1;
+
+ /**
+ * Hide 'home' elements in this action bar, leaving more space for other
+ * navigation elements. This includes logo and icon.
+ */
+ public static final int DISPLAY_HIDE_HOME = 0x2;
+
+ /**
+ * Set the callback that the ActionBar will use to handle events
+ * and populate menus.
+ * @param callback Callback to use
+ */
+ public abstract void setCallback(Callback callback);
+
+ /**
+ * Set a custom navigation view.
+ *
+ * Custom navigation views appear between the application icon and
+ * any action buttons and may use any space available there. Common
+ * use cases for custom navigation views might include an address bar
+ * for a browser or other navigation mechanisms that do not translate
+ * well to provided navigation modes.
+ *
+ * Setting a non-null custom navigation view will also set the
+ * navigation mode to NAVMODE_CUSTOM.
+ *
+ * @param view Custom navigation view to place in the ActionBar.
+ */
+ public abstract void setCustomNavigationView(View view);
+
+ /**
+ * Set the ActionBar's title.
+ *
+ * This is set automatically to the name of your Activity,
+ * but may be changed here.
+ *
+ * @param title Title text
+ */
+ public abstract void setTitle(CharSequence title);
+
+ /**
+ * Set the ActionBar's subtitle.
+ *
+ * The subtitle is usually displayed as a second line of text
+ * under the title. Good for extended descriptions of activity state.
+ *
+ * @param subtitle Subtitle text.
+ */
+ public abstract void setSubtitle(CharSequence subtitle);
+
+ /**
+ * Set the navigation mode.
+ *
+ * @param mode One of {@link #NAVIGATION_MODE_NORMAL}, {@link #NAVIGATION_MODE_DROPDOWN_LIST},
+ * {@link #NAVIGATION_MODE_TABS}, or {@link #NAVIGATION_MODE_CUSTOM}.
+ */
+ public abstract void setNavigationMode(int mode);
+
+ /**
+ * Set display options.
+ *
+ * @param options A combination of the bits defined by the DISPLAY_ constants
+ * defined in ActionBar.
+ */
+ public abstract void setDisplayOptions(int options);
+
+ /**
+ * Set the ActionBar's background.
+ *
+ * @param d Background drawable
+ */
+ public abstract void setBackgroundDrawable(Drawable d);
+
+ /**
+ * Set a drawable to use as a divider between sections of the ActionBar.
+ *
+ * @param d Divider drawable
+ */
+ public abstract void setDividerDrawable(Drawable d);
+
+ /**
+ * @return The current custom navigation view.
+ */
+ public abstract View getCustomNavigationView();
+
+ /**
+ * @return The current ActionBar title.
+ */
+ public abstract CharSequence getTitle();
+
+ /**
+ * @return The current ActionBar subtitle.
+ */
+ public abstract CharSequence getSubtitle();
+
+ /**
+ * @return The current navigation mode.
+ */
+ public abstract int getNavigationMode();
+
+ /**
+ * @return The current set of display options.
+ */
+ public abstract int getDisplayOptions();
+
+ /**
+ * Request an update of the items in the action menu.
+ * This will result in a call to Callback.onUpdateActionMenu(Menu)
+ * and the ActionBar will update based on any changes made there.
+ */
+ public abstract void updateActionMenu();
+
+ /**
+ * Callback interface for ActionBar events.
+ */
+ public interface Callback {
+ /**
+ * Initialize the always-visible contents of the action bar.
+ * You should place your menu items into <var>menu</var>.
+ *
+ * <p>This is only called once, the first time the action bar is displayed.
+ *
+ * @param menu The action menu in which to place your items.
+ * @return You must return true for actions to be displayed;
+ * if you return false they will not be shown.
+ *
+ * @see #onActionItemSelected(MenuItem)
+ */
+ public boolean onCreateActionMenu(Menu menu);
+
+ /**
+ * Update the action bar. This is called in response to {@link #updateActionMenu()}
+ * calls, which may be application-initiated or the result of changing fragment state.
+ *
+ * @return true if the action bar should update based on altered menu contents,
+ * false if no changes are necessary.
+ */
+ public boolean onUpdateActionMenu(Menu menu);
+
+ /**
+ * This hook is called whenever an item in your action bar is selected.
+ * The default implementation simply returns false to have the normal
+ * processing happen (sending a message to its handler). You can use this
+ * method for any items for which you would like to do processing without
+ * those other facilities.
+ *
+ * @param item The action bar item that was selected.
+ * @return boolean Return false to allow normal menu processing to proceed,
+ * true to consume it here.
+ */
+ public boolean onActionItemSelected(MenuItem item);
+
+ /*
+ * In progress
+ */
+ public boolean onCreateContextMode(int modeId, Menu menu);
+ public boolean onPrepareContextMode(int modeId, Menu menu);
+ public boolean onContextItemSelected(int modeId, MenuItem item);
+ }
+
+ /**
+ * Simple stub implementations of ActionBar.Callback methods.
+ * Extend this if you only need a subset of Callback functionality.
+ */
+ public static class SimpleCallback implements Callback {
+ public boolean onCreateActionMenu(Menu menu) {
+ return false;
+ }
+
+ public boolean onUpdateActionMenu(Menu menu) {
+ return false;
+ }
+
+ public boolean onActionItemSelected(MenuItem item) {
+ return false;
+ }
+
+ public boolean onCreateContextMode(int modeId, Menu menu) {
+ return false;
+ }
+
+ public boolean onPrepareContextMode(int modeId, Menu menu) {
+ return false;
+ }
+
+ public boolean onContextItemSelected(int modeId, MenuItem item) {
+ return false;
+ }
+ }
+
+}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 5cb8f89..21c6d2a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,14 +16,16 @@
package android.app;
-import com.android.internal.policy.PolicyManager;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
import android.content.ComponentCallbacks;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.IIntentSender;
+import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
@@ -50,6 +52,7 @@
import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
+import android.view.ActionBarView;
import android.view.ContextMenu;
import android.view.ContextThemeWrapper;
import android.view.InflateException;
@@ -69,10 +72,10 @@
import android.view.ViewGroup.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
+import android.widget.LinearLayout;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.HashMap;
+import com.android.internal.app.SplitActionBar;
+import com.android.internal.policy.PolicyManager;
/**
* An activity is a single, focused thing that the user can do. Almost all
@@ -637,6 +640,8 @@
private boolean mStopped;
boolean mFinished;
boolean mStartedActivity;
+ /** true if the activity is being destroyed in order to recreate it with a new configuration */
+ /*package*/ boolean mChangingConfigurations = false;
/*package*/ int mConfigChangeFlags;
/*package*/ Configuration mCurrentConfig;
private SearchManager mSearchManager;
@@ -648,6 +653,7 @@
/*package*/ boolean mWindowAdded = false;
/*package*/ boolean mVisibleFromServer = false;
/*package*/ boolean mVisibleFromClient = true;
+ /*package*/ ActionBar mActionBar = null;
private CharSequence mTitle;
private int mTitleColor = 0;
@@ -1791,7 +1797,19 @@
public View findViewById(int id) {
return getWindow().findViewById(id);
}
-
+
+ /**
+ * Retrieve a reference to this activity's ActionBar.
+ *
+ * <p><em>Note:</em> The ActionBar is initialized when a content view
+ * is set. This function will return null if called before {@link #setContentView}
+ * or {@link #addContentView}.
+ * @return The Activity's ActionBar, or null if it does not have one.
+ */
+ public ActionBar getActionBar() {
+ return mActionBar;
+ }
+
/**
* Finds a fragment that was identified by the given id either when inflated
* from XML or as the container ID when added in a transaction. This only
@@ -1803,6 +1821,27 @@
}
/**
+ * Creates a new ActionBar, locates the inflated ActionBarView,
+ * initializes the ActionBar with the view, and sets mActionBar.
+ */
+ private void initActionBar() {
+ if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) {
+ return;
+ }
+
+ ActionBarView view = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ if (view != null) {
+ LinearLayout splitView =
+ (LinearLayout) findViewById(com.android.internal.R.id.context_action_bar);
+ if (splitView != null) {
+ mActionBar = new SplitActionBar(view, splitView);
+ }
+ } else {
+ Log.e(TAG, "Could not create action bar; view not found in window decor.");
+ }
+ }
+
+ /**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
*
@@ -1810,6 +1849,7 @@
*/
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
+ initActionBar();
}
/**
@@ -1821,6 +1861,7 @@
*/
public void setContentView(View view) {
getWindow().setContentView(view);
+ initActionBar();
}
/**
@@ -1833,6 +1874,7 @@
*/
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
+ initActionBar();
}
/**
@@ -1844,6 +1886,7 @@
*/
public void addContentView(View view, ViewGroup.LayoutParams params) {
getWindow().addContentView(view, params);
+ initActionBar();
}
/**
@@ -3402,6 +3445,19 @@
}
/**
+ * Check to see whether this activity is in the process of being destroyed in order to be
+ * recreated with a new configuration. This is often used in
+ * {@link #onStop} to determine whether the state needs to be cleaned up or will be passed
+ * on to the next instance of the activity via {@link #onRetainNonConfigurationInstance()}.
+ *
+ * @return If the activity is being torn down in order to be recreated with a new configuration,
+ * returns true; else returns false.
+ */
+ public boolean isChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+
+ /**
* Call this when your activity is done and should be closed. The
* ActivityResult is propagated back to whoever launched you via
* onActivityResult().
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index acedcdb..3ec8bba 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3575,6 +3575,9 @@
if (finishing) {
r.activity.mFinished = true;
}
+ if (getNonConfigInstance) {
+ r.activity.mChangingConfigurations = true;
+ }
if (!r.paused) {
try {
r.activity.mCalled = false;
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 7ed7c49..b937dd6 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1058,19 +1058,21 @@
}
public void callActivityOnDestroy(Activity activity) {
- if (mWaitingActivities != null) {
- synchronized (mSync) {
- final int N = mWaitingActivities.size();
- for (int i=0; i<N; i++) {
- final ActivityWaiter aw = mWaitingActivities.get(i);
- final Intent intent = aw.intent;
- if (intent.filterEquals(activity.getIntent())) {
- aw.activity = activity;
- mMessageQueue.addIdleHandler(new ActivityGoing(aw));
- }
- }
- }
- }
+ // TODO: the following block causes intermittent hangs when using startActivity
+ // temporarily comment out until root cause is fixed (bug 2630683)
+// if (mWaitingActivities != null) {
+// synchronized (mSync) {
+// final int N = mWaitingActivities.size();
+// for (int i=0; i<N; i++) {
+// final ActivityWaiter aw = mWaitingActivities.get(i);
+// final Intent intent = aw.intent;
+// if (intent.filterEquals(activity.getIntent())) {
+// aw.activity = activity;
+// mMessageQueue.addIdleHandler(new ActivityGoing(aw));
+// }
+// }
+// }
+// }
activity.performDestroy();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ed548c5..2acc4a0 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1866,7 +1866,7 @@
* @hide
*/
public static final String ACTION_REMOTE_INTENT =
- "com.google.android.pushmessaging.intent.RECEIVE";
+ "com.google.android.c2dm.intent.RECEIVE";
/**
* Broadcast Action: hook for permforming cleanup after a system update.
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index dc4471e..7a2546d 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -25,6 +25,9 @@
/**
* This interface provides random read-write access to the result set returned
* by a database query.
+ *
+ * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
+ * threads should perform its own synchronization when using the Cursor.
*/
public interface Cursor {
/**
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index fea3438..f3382dc 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -38,6 +38,9 @@
/**
* A Cursor implementation that exposes results from a query on a
* {@link SQLiteDatabase}.
+ *
+ * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple
+ * threads should perform its own synchronization when using the SQLiteCursor.
*/
public class SQLiteCursor extends AbstractWindowedCursor {
static final String TAG = "Cursor";
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index e64e2c3..47de286 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1180,7 +1180,8 @@
*
* @param sql The raw SQL statement, may contain ? for unknown values to be
* bound later.
- * @return a pre-compiled statement object.
+ * @return A pre-compiled {@link SQLiteStatement} object. Note that
+ * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
*/
public SQLiteStatement compileStatement(String sql) throws SQLException {
lock();
@@ -1221,7 +1222,8 @@
* default sort order, which may be unordered.
* @param limit Limits the number of rows returned by the query,
* formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A Cursor object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
* @see Cursor
*/
public Cursor query(boolean distinct, String table, String[] columns,
@@ -1259,7 +1261,8 @@
* default sort order, which may be unordered.
* @param limit Limits the number of rows returned by the query,
* formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A Cursor object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
* @see Cursor
*/
public Cursor queryWithFactory(CursorFactory cursorFactory,
@@ -1300,7 +1303,8 @@
* @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
* (excluding the ORDER BY itself). Passing null will use the
* default sort order, which may be unordered.
- * @return A {@link Cursor} object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
* @see Cursor
*/
public Cursor query(String table, String[] columns, String selection,
@@ -1337,7 +1341,8 @@
* default sort order, which may be unordered.
* @param limit Limits the number of rows returned by the query,
* formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A {@link Cursor} object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
* @see Cursor
*/
public Cursor query(String table, String[] columns, String selection,
@@ -1355,7 +1360,8 @@
* @param selectionArgs You may include ?s in where clause in the query,
* which will be replaced by the values from selectionArgs. The
* values will be bound as Strings.
- * @return A {@link Cursor} object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
*/
public Cursor rawQuery(String sql, String[] selectionArgs) {
return rawQueryWithFactory(null, sql, selectionArgs, null);
@@ -1370,7 +1376,8 @@
* which will be replaced by the values from selectionArgs. The
* values will be bound as Strings.
* @param editTable the name of the first table, which is editable
- * @return A {@link Cursor} object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
*/
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
@@ -1425,7 +1432,8 @@
* values will be bound as Strings.
* @param initialRead set the initial count of items to read from the cursor
* @param maxRead set the count of items to read on each iteration after the first
- * @return A {@link Cursor} object, which is positioned before the first entry
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
*
* This work is incomplete and not fully tested or reviewed, so currently
* hidden.
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index a9c1ac6..c37385c0 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -20,6 +20,9 @@
/**
* A base class for compiled SQLite programs.
+ *
+ * SQLiteProgram is not internally synchronized so code using a SQLiteProgram from multiple
+ * threads should perform its own synchronization when using the SQLiteProgram.
*/
public abstract class SQLiteProgram extends SQLiteClosable {
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 43d2fac..905b66b 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -23,6 +23,9 @@
/**
* A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
* This class is used by SQLiteCursor and isn't useful itself.
+ *
+ * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple
+ * threads should perform its own synchronization when using the SQLiteQuery.
*/
public class SQLiteQuery extends SQLiteProgram {
private static final String TAG = "Cursor";
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 98da414..47cca87 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -23,6 +23,9 @@
* The statement cannot return multiple rows, but 1x1 result sets are allowed.
* Don't use SQLiteStatement constructor directly, please use
* {@link SQLiteDatabase#compileStatement(String)}
+ *
+ * SQLiteStatement is not internally synchronized so code using a SQLiteStatement from multiple
+ * threads should perform its own synchronization when using the SQLiteStatement.
*/
public class SQLiteStatement extends SQLiteProgram
{
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 98f32b3..214510d 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -310,6 +310,9 @@
case TelephonyManager.NETWORK_TYPE_EVDO_A:
networkTypeStr = "evdo";
break;
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ networkTypeStr = "evdo";
+ break;
}
return "net.tcp.buffersize." + networkTypeStr;
}
diff --git a/core/java/android/text/GraphicsOperations.java b/core/java/android/text/GraphicsOperations.java
index c3bd0ae..05697c6 100644
--- a/core/java/android/text/GraphicsOperations.java
+++ b/core/java/android/text/GraphicsOperations.java
@@ -34,6 +34,13 @@
float x, float y, Paint p);
/**
+ * Just like {@link Canvas#drawTextRun}.
+ * {@hide}
+ */
+ void drawTextRun(Canvas c, int start, int end,
+ float x, float y, int flags, Paint p);
+
+ /**
* Just like {@link Paint#measureText}.
*/
float measureText(int start, int end, Paint p);
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index caaafa1..7563179 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -17,8 +17,9 @@
package android.text;
import com.android.internal.util.ArrayUtils;
-import android.graphics.Paint;
+
import android.graphics.Canvas;
+import android.graphics.Paint;
import java.lang.reflect.Array;
@@ -780,7 +781,7 @@
}
if (count == 0) {
- return (T[]) ArrayUtils.emptyArray(kind);
+ return ArrayUtils.emptyArray(kind);
}
if (count == 1) {
ret = (Object[]) Array.newInstance(kind, 1);
@@ -1055,6 +1056,39 @@
}
/**
+ * Don't call this yourself -- exists for Canvas to use internally.
+ * {@hide}
+ */
+ public void drawTextRun(Canvas c, int start, int end,
+ float x, float y, int flags, Paint p) {
+ checkRange("drawTextRun", start, end);
+
+ // Assume context requires no more than 8 chars on either side.
+ // This is ample, only decomposed U+FDFA falls into this
+ // category, and no one should put a style break within it
+ // anyway.
+ int cstart = start - 8;
+ if (cstart < 0) {
+ cstart = 0;
+ }
+ int cend = end + 8;
+ int max = length();
+ if (cend > max) {
+ cend = max;
+ }
+ if (cend <= mGapStart) {
+ c.drawTextRun(mText, start, end - start, x, y, flags, p);
+ } else if (cstart >= mGapStart) {
+ c.drawTextRun(mText, start + mGapLength, end - start, x, y, flags, p);
+ } else {
+ char[] buf = TextUtils.obtain(cend - cstart);
+ getChars(cstart, cend, buf, 0);
+ c.drawTextRun(buf, start - cstart, end - start, x, y, flags, p);
+ TextUtils.recycle(buf);
+ }
+ }
+
+ /**
* Don't call this yourself -- exists for Paint to use internally.
* {@hide}
*/
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 4aeabf3..fae3fc3 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -951,48 +951,11 @@
private void drawTextRun(Canvas c, TextPaint wp, int start, int limit,
boolean runIsRtl, float x, int y) {
- // Since currently skia only renders text left-to-right, we need to
- // put the shaped characters into visual order before rendering.
- // Since we might want to re-render the line again, we swap them
- // back when we're done. If we left them swapped, measurement
- // would be broken since it expects the characters in logical order.
- if (runIsRtl) {
- swapRun(start, limit);
- }
+ int flags = runIsRtl ? Canvas.DIRECTION_RTL : Canvas.DIRECTION_LTR;
if (mCharsValid) {
- c.drawText(mChars, start, limit - start, x, y, wp);
+ c.drawTextRun(mChars, start, limit - start, x, y, flags, wp);
} else {
- c.drawText(mText, mStart + start, mStart + limit, x, y, wp);
- }
- if (runIsRtl) {
- swapRun(start, limit);
- }
- }
-
- /**
- * Reverses the order of characters in the chars array between start and
- * limit, used by drawTextRun.
- * @param start the start of the run to reverse
- * @param limit the limit of the run to reverse
- */
- private void swapRun(int start, int limit) {
- // First we swap all the characters one for one, then we
- // do another pass looking for surrogate pairs and swapping them
- // back into their logical order.
- char[] chars = mChars;
- for (int s = start, e = limit - 1; s < e; ++s, --e) {
- char ch = chars[s]; chars[s] = chars[e]; chars[e] = ch;
- }
-
- for (int s = start, e = limit - 1; s < e; ++s) {
- char c1 = chars[s];
- if (c1 >= 0xdc00 && c1 < 0xe000) {
- char c2 = chars[s+1];
- if (c2 >= 0xd800 && c2 < 0xdc00) {
- chars[s++] = c2;
- chars[s] = c1;
- }
- }
+ c.drawTextRun(mText, mStart + start, mStart + limit, x, y, flags, wp);
}
}
diff --git a/core/java/android/view/ActionBarView.java b/core/java/android/view/ActionBarView.java
new file mode 100644
index 0000000..941ef21
--- /dev/null
+++ b/core/java/android/view/ActionBarView.java
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import java.util.ArrayList;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.ActionBar.Callback;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.SparseArray;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.view.menu.ActionMenu;
+import com.android.internal.view.menu.ActionMenuItem;
+
+/**
+ * @hide
+ */
+public class ActionBarView extends ViewGroup {
+ private static final String TAG = "ActionBarView";
+
+ // TODO: This must be defined in the default theme
+ private static final int CONTENT_HEIGHT_DIP = 50;
+ private static final int CONTENT_PADDING_DIP = 3;
+ private static final int CONTENT_SPACING_DIP = 6;
+ private static final int CONTENT_ACTION_SPACING_DIP = 12;
+
+ /**
+ * Display options applied by default
+ */
+ public static final int DISPLAY_DEFAULT = 0;
+
+ /**
+ * Display options that require re-layout as opposed to a simple invalidate
+ */
+ private static final int DISPLAY_RELAYOUT_MASK = ActionBar.DISPLAY_USE_LOGO;
+
+ private final int mContentHeight;
+
+ private int mNavigationMode;
+ private int mDisplayOptions;
+ private int mSpacing;
+ private int mActionSpacing;
+ private CharSequence mTitle;
+ private CharSequence mSubtitle;
+ private Drawable mIcon;
+ private Drawable mLogo;
+ private Drawable mDivider;
+
+ private ImageView mIconView;
+ private ImageView mLogoView;
+ private TextView mTitleView;
+ private TextView mSubtitleView;
+ private View mNavigationView;
+
+ private boolean mShowMenu;
+
+ private ActionMenuItem mLogoNavItem;
+ private ActionMenu mNavMenu;
+ private ActionMenu mActionMenu;
+ private ActionMenu mOptionsMenu;
+
+ private SparseArray<ActionMenu> mContextMenus;
+
+ private Callback mCallback;
+
+ private final ArrayList<ActionView> mActions = new ArrayList<ActionView>();
+ private final OnClickListener mActionClickHandler = new OnClickListener() {
+ public void onClick(View v) {
+ ActionView av = (ActionView) v;
+ ActionMenuItem item = (ActionMenuItem) av.menuItem;
+
+ if (!mCallback.onActionItemSelected(item)) {
+ item.invoke();
+ }
+ }
+ };
+
+ private OnClickListener mHomeClickListener = null;
+
+ public ActionBarView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ mContentHeight = (int) (CONTENT_HEIGHT_DIP * metrics.density + 0.5f);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar);
+
+ final int colorFilter = a.getColor(R.styleable.ActionBar_colorFilter, 0);
+
+ if (colorFilter != 0) {
+ final Drawable d = getBackground();
+ d.setDither(true);
+ d.setColorFilter(new PorterDuffColorFilter(colorFilter, PorterDuff.Mode.OVERLAY));
+ }
+
+ ApplicationInfo info = context.getApplicationInfo();
+ PackageManager pm = context.getPackageManager();
+ mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode, ActionBar.NAVIGATION_MODE_NORMAL);
+ mTitle = a.getText(R.styleable.ActionBar_title);
+ mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
+ mDisplayOptions = a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT);
+
+ mLogo = a.getDrawable(R.styleable.ActionBar_logo);
+ if (mLogo == null) {
+ mLogo = info.loadLogo(pm);
+ }
+ mIcon = a.getDrawable(R.styleable.ActionBar_icon);
+ if (mIcon == null) {
+ mIcon = info.loadIcon(pm);
+ }
+ mDivider = a.getDrawable(R.styleable.ActionBar_divider);
+
+ Drawable background = a.getDrawable(R.styleable.ActionBar_background);
+ if (background != null) {
+ setBackgroundDrawable(background);
+ }
+
+ final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
+ if (customNavId != 0) {
+ LayoutInflater inflater = LayoutInflater.from(context);
+ mNavigationView = (View) inflater.inflate(customNavId, null);
+ mNavigationMode = ActionBar.NAVIGATION_MODE_CUSTOM;
+ }
+
+ a.recycle();
+
+ // TODO: Set this in the theme
+ int padding = (int) (CONTENT_PADDING_DIP * metrics.density + 0.5f);
+ setPadding(padding, padding, padding, padding);
+
+ mSpacing = (int) (CONTENT_SPACING_DIP * metrics.density + 0.5f);
+ mActionSpacing = (int) (CONTENT_ACTION_SPACING_DIP * metrics.density + 0.5f);
+
+ if (mLogo != null || mIcon != null || mTitle != null) {
+ mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
+ mHomeClickListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCallback != null) {
+ mCallback.onActionItemSelected(mLogoNavItem);
+ }
+ }
+ };
+ }
+
+ mContextMenus = new SparseArray<ActionMenu>();
+ }
+
+ private boolean initOptionsMenu() {
+ final Context context = getContext();
+ if (!(context instanceof Activity)) {
+ return false;
+ }
+
+ final Activity activity = (Activity) context;
+ ActionMenu optionsMenu = new ActionMenu(context);
+ if (activity.onCreateOptionsMenu(optionsMenu)) {
+ mOptionsMenu = optionsMenu;
+ return true;
+ }
+
+ return false;
+ }
+
+ public void setCallback(Callback callback) {
+ final Context context = getContext();
+ mCallback = callback;
+
+ ActionMenu actionMenu = new ActionMenu(context);
+ if (callback.onCreateActionMenu(actionMenu)) {
+ mActionMenu = actionMenu;
+ performUpdateActionMenu();
+ }
+ }
+
+ public void setCustomNavigationView(View view) {
+ mNavigationView = view;
+ if (view != null) {
+ setNavigationMode(ActionBar.NAVIGATION_MODE_CUSTOM);
+ }
+ requestLayout();
+ }
+
+ public void setDividerDrawable(Drawable d) {
+ mDivider = d;
+ }
+
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ public void setTitle(CharSequence title) {
+ mTitle = title;
+ if (mTitleView != null) {
+ mTitleView.setText(title);
+ }
+ if (mLogoNavItem != null) {
+ mLogoNavItem.setTitle(title);
+ }
+ }
+
+ public CharSequence getSubtitle() {
+ return mSubtitle;
+ }
+
+ public void setSubtitle(CharSequence subtitle) {
+ mSubtitle = subtitle;
+ if (mSubtitleView != null) {
+ mSubtitleView.setText(subtitle);
+ }
+ }
+
+ public void setDisplayOptions(int options) {
+ final int flagsChanged = options & mDisplayOptions;
+ mDisplayOptions = options;
+ if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
+ requestLayout();
+ } else {
+ invalidate();
+ }
+ }
+
+ public void setNavigationMode(int mode) {
+ if (mode != mNavigationMode) {
+ mNavigationMode = mode;
+ requestLayout();
+ }
+ }
+
+ public View getCustomNavigationView() {
+ return mNavigationView;
+ }
+
+ public int getNavigationMode() {
+ return mNavigationMode;
+ }
+
+ public int getDisplayOptions() {
+ return mDisplayOptions;
+ }
+
+ private ActionView findActionViewForItem(MenuItem item) {
+ final ArrayList<ActionView> actions = mActions;
+ final int actionCount = actions.size();
+ for (int i = 0; i < actionCount; i++) {
+ ActionView av = actions.get(i);
+ if (av.menuItem.equals(item)) {
+ return av;
+ }
+ }
+ return null;
+ }
+
+ public void setContextMode(int mode) {
+ Callback callback = mCallback;
+ if (callback == null) {
+ throw new IllegalStateException(
+ "Attempted to set ActionBar context mode with no callback");
+ }
+
+ ActionMenu menu = mContextMenus.get(mode);
+ if (menu == null) {
+ // Initialize the new mode
+ menu = new ActionMenu(getContext());
+
+ if (!callback.onCreateContextMode(mode, menu)) {
+ throw new IllegalArgumentException(
+ "ActionBar callback does not know how to create context mode " + mode);
+ }
+ mContextMenus.put(mode, menu);
+ }
+
+ if (callback.onPrepareContextMode(mode, menu)) {
+ // TODO Set mode, animate, etc.
+ }
+ }
+
+ public void exitContextMode() {
+ // TODO Turn off context mode; go back to normal.
+ }
+
+ public void updateActionMenu() {
+ final ActionMenu menu = mActionMenu;
+ if (menu == null || mCallback == null || !mCallback.onUpdateActionMenu(menu)) {
+ return;
+ }
+ performUpdateActionMenu();
+ }
+
+ private void performUpdateActionMenu() {
+ final ActionMenu menu = mActionMenu;
+ if (menu == null) {
+ return;
+ }
+ final Context context = getContext();
+
+ int childCount = getChildCount();
+ int childIndex = 0;
+ while (childIndex < childCount) {
+ View v = getChildAt(childIndex);
+ if (v instanceof ActionView) {
+ detachViewFromParent(childIndex);
+ childCount--;
+ } else {
+ childIndex++;
+ }
+ }
+
+ ArrayList<ActionView> detachedViews = new ArrayList<ActionView>(mActions);
+ final int itemCount = menu.size();
+ for (int i = 0; i < itemCount; i++) {
+ final MenuItem item = menu.getItem(i);
+
+ boolean newView = false;
+ ActionView actionView = findActionViewForItem(item);
+ if (actionView == null) {
+ actionView = new ActionView(context);
+ newView = true;
+ }
+ actionView.actionId = item.getItemId();
+ actionView.menuItem = item;
+ actionView.actionLabel = item.getTitle();
+ actionView.setAdjustViewBounds(true);
+ actionView.setImageDrawable(item.getIcon());
+ actionView.setOnClickListener(mActionClickHandler);
+
+ LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, LayoutParams.ITEM_TYPE_ACTION);
+ actionView.setLayoutParams(layoutParams);
+
+ if (newView) {
+ addView(actionView);
+ mActions.add(actionView);
+ } else {
+ attachViewToParent(actionView, -1, layoutParams);
+ detachedViews.remove(actionView);
+ actionView.invalidate();
+ }
+ }
+
+ final int detachedCount = detachedViews.size();
+ for (int i = 0; i < detachedCount; i++) {
+ removeDetachedView(detachedViews.get(i), false);
+ }
+
+ requestLayout();
+ }
+
+ public void addAction(int id, Drawable icon, CharSequence label, OnActionListener listener) {
+ ActionView actionView = new ActionView(getContext());
+ actionView.actionId = id;
+ actionView.actionLabel = label;
+ actionView.actionListener = listener;
+ actionView.setAdjustViewBounds(true);
+ actionView.setImageDrawable(icon);
+ actionView.setOnClickListener(mActionClickHandler);
+
+ actionView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, LayoutParams.ITEM_TYPE_ACTION));
+
+ addView(actionView);
+ mActions.add(actionView);
+
+ requestLayout();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ if ((mDisplayOptions & ActionBar.DISPLAY_HIDE_HOME) == 0) {
+ if (mLogo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
+ mLogoView = new ImageView(getContext());
+ mLogoView.setAdjustViewBounds(true);
+ mLogoView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, LayoutParams.ITEM_TYPE_ICON));
+ mLogoView.setImageDrawable(mLogo);
+ mLogoView.setClickable(true);
+ mLogoView.setOnClickListener(mHomeClickListener);
+ addView(mLogoView);
+ } else if (mIcon != null) {
+ mIconView = new ImageView(getContext());
+ mIconView.setAdjustViewBounds(true);
+ mIconView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, LayoutParams.ITEM_TYPE_ICON));
+ mIconView.setImageDrawable(mIcon);
+ mIconView.setClickable(true);
+ mIconView.setOnClickListener(mHomeClickListener);
+ addView(mIconView);
+ }
+ }
+
+ switch (mNavigationMode) {
+ case ActionBar.NAVIGATION_MODE_NORMAL:
+ if (mLogoView == null) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ mTitleView = (TextView) inflater.inflate(R.layout.action_bar_title_item, null);
+ mTitleView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT, LayoutParams.ITEM_TYPE_TITLE));
+ if (mTitle != null) {
+ mTitleView.setText(mTitle);
+ }
+ mTitleView.setClickable(true);
+ mTitleView.setOnClickListener(mHomeClickListener);
+ addView(mTitleView);
+ }
+ break;
+
+ case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST:
+ throw new UnsupportedOperationException(
+ "Dropdown list navigation isn't supported yet!");
+
+ case ActionBar.NAVIGATION_MODE_TABS:
+ throw new UnsupportedOperationException(
+ "Tab navigation isn't supported yet!");
+
+ case ActionBar.NAVIGATION_MODE_CUSTOM:
+ if (mNavigationView != null) {
+ mNavigationView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT, LayoutParams.ITEM_TYPE_CUSTOM_NAV));
+ addView(mNavigationView);
+ }
+ break;
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ if (widthMode != MeasureSpec.EXACTLY) {
+ throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
+ "with android:layout_width=\"match_parent\" (or fill_parent)");
+ }
+
+ int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ if (heightMode != MeasureSpec.AT_MOST) {
+ throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
+ "with android:layout_height=\"wrap_content\"");
+ }
+
+ int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
+
+ int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
+ int childSpecHeight = MeasureSpec.makeMeasureSpec(mContentHeight - getPaddingTop() -
+ getPaddingBottom(), MeasureSpec.AT_MOST);
+
+ if (mLogoView != null) {
+ availableWidth = measureChildView(mLogoView, availableWidth, childSpecHeight, mSpacing);
+ }
+ if (mIconView != null) {
+ availableWidth = measureChildView(mIconView, availableWidth, childSpecHeight, mSpacing);
+ }
+
+ final ArrayList<ActionView> actions = mActions;
+ final int actionCount = actions.size();
+ for (int i = 0; i < actionCount; i++) {
+ ActionView action = actions.get(i);
+ availableWidth = measureChildView(action, availableWidth,
+ childSpecHeight, mActionSpacing);
+ }
+
+ switch (mNavigationMode) {
+ case ActionBar.NAVIGATION_MODE_NORMAL:
+ if (mTitleView != null) {
+ availableWidth = measureChildView(mTitleView, availableWidth,
+ childSpecHeight, mSpacing);
+ }
+ break;
+ case ActionBar.NAVIGATION_MODE_CUSTOM:
+ if (mNavigationView != null) {
+ availableWidth = measureChildView(mNavigationView, availableWidth,
+ childSpecHeight, mSpacing);
+ }
+ break;
+ }
+
+ setMeasuredDimension(contentWidth, mContentHeight);
+ }
+
+ private int measureChildView(View child, int availableWidth, int childSpecHeight, int spacing) {
+ measureChild(child,
+ MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
+ childSpecHeight);
+
+ availableWidth -= child.getMeasuredWidth();
+ availableWidth -= spacing;
+
+ return availableWidth;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ int x = getPaddingLeft();
+ final int y = getPaddingTop();
+ final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
+
+ if (mLogoView != null) {
+ x += positionChild(mLogoView, x, y, contentHeight) + mSpacing;
+ }
+ if (mIconView != null) {
+ x += positionChild(mIconView, x, y, contentHeight) + mSpacing;
+ }
+
+ switch (mNavigationMode) {
+ case ActionBar.NAVIGATION_MODE_NORMAL:
+ if (mTitleView != null) {
+ x += positionChild(mTitleView, x, y, contentHeight) + mSpacing;
+ }
+ break;
+
+ case ActionBar.NAVIGATION_MODE_CUSTOM:
+ if (mNavigationView != null) {
+ x += positionChild(mNavigationView, x, y, contentHeight) + mSpacing;
+ }
+ break;
+ }
+
+ x = r - l - getPaddingRight();
+
+ final int count = mActions.size();
+ for (int i = count - 1; i >= 0; i--) {
+ ActionView action = mActions.get(i);
+ x -= (positionChildInverse(action, x, y, contentHeight) + mActionSpacing);
+ }
+ }
+
+ private int positionChild(View child, int x, int y, int contentHeight) {
+ int childWidth = child.getMeasuredWidth();
+ int childHeight = child.getMeasuredHeight();
+ int childTop = y + (contentHeight - childHeight) / 2;
+
+ child.layout(x, childTop, x + childWidth, childTop + childHeight);
+
+ return childWidth;
+ }
+
+ private int positionChildInverse(View child, int x, int y, int contentHeight) {
+ int childWidth = child.getMeasuredWidth();
+ int childHeight = child.getMeasuredHeight();
+ int childTop = y + (contentHeight - childHeight) / 2;
+
+ child.layout(x - childWidth, childTop, x, childTop + childHeight);
+
+ return childWidth;
+ }
+
+ @Override
+ public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new ViewGroup.LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p != null && p instanceof LayoutParams;
+ }
+
+ private static class LayoutParams extends ViewGroup.LayoutParams {
+ static final int ITEM_TYPE_UNKNOWN = -1;
+ static final int ITEM_TYPE_ICON = 0;
+ static final int ITEM_TYPE_TITLE = 1;
+ static final int ITEM_TYPE_CUSTOM_NAV = 2;
+ static final int ITEM_TYPE_ACTION = 3;
+ static final int ITEM_TYPE_MORE = 4;
+
+ int type = ITEM_TYPE_UNKNOWN;
+
+ public LayoutParams(Context c, AttributeSet attrs) {
+ super(c, attrs);
+ }
+
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ public LayoutParams(int width, int height, int type) {
+ this(width, height);
+ this.type = type;
+ }
+
+
+ public LayoutParams(ViewGroup.LayoutParams source) {
+ super(source);
+ }
+ }
+
+ public interface OnActionListener {
+ void onAction(int id);
+ }
+
+ private static class ActionView extends ImageView {
+ int actionId;
+ CharSequence actionLabel;
+ OnActionListener actionListener;
+ MenuItem menuItem;
+
+ public ActionView(Context context) {
+ super(context);
+ }
+ }
+}
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index 46c805c..a37d83d 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -16,9 +16,8 @@
package android.view;
-import com.android.internal.view.menu.MenuItemImpl;
-
import java.io.IOException;
+import java.lang.reflect.Method;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -30,6 +29,8 @@
import android.util.AttributeSet;
import android.util.Xml;
+import com.android.internal.view.menu.MenuItemImpl;
+
/**
* This class is used to instantiate menu XML files into Menu objects.
* <p>
@@ -166,6 +167,41 @@
}
}
+ private static class InflatedOnMenuItemClickListener
+ implements MenuItem.OnMenuItemClickListener {
+ private static final Class[] PARAM_TYPES = new Class[] { MenuItem.class };
+
+ private Context mContext;
+ private Method mMethod;
+
+ public InflatedOnMenuItemClickListener(Context context, String methodName) {
+ mContext = context;
+ Class c = context.getClass();
+ try {
+ mMethod = c.getMethod(methodName, PARAM_TYPES);
+ } catch (Exception e) {
+ InflateException ex = new InflateException(
+ "Couldn't resolve menu item onClick handler " + methodName +
+ " in class " + c.getName());
+ ex.initCause(e);
+ throw ex;
+ }
+ }
+
+ public boolean onMenuItemClick(MenuItem item) {
+ try {
+ if (mMethod.getReturnType() == Boolean.TYPE) {
+ return (Boolean) mMethod.invoke(mContext, item);
+ } else {
+ mMethod.invoke(mContext, item);
+ return true;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
/**
* State for the current menu.
* <p>
@@ -205,6 +241,8 @@
private boolean itemVisible;
private boolean itemEnabled;
+ private String itemListenerMethodName;
+
private static final int defaultGroupId = NO_ID;
private static final int defaultItemId = NO_ID;
private static final int defaultItemCategory = 0;
@@ -276,6 +314,7 @@
itemChecked = a.getBoolean(com.android.internal.R.styleable.MenuItem_checked, defaultItemChecked);
itemVisible = a.getBoolean(com.android.internal.R.styleable.MenuItem_visible, groupVisible);
itemEnabled = a.getBoolean(com.android.internal.R.styleable.MenuItem_enabled, groupEnabled);
+ itemListenerMethodName = a.getString(com.android.internal.R.styleable.MenuItem_onClick);
a.recycle();
@@ -299,8 +338,13 @@
.setIcon(itemIconResId)
.setAlphabeticShortcut(itemAlphabeticShortcut)
.setNumericShortcut(itemNumericShortcut);
+
+ if (itemListenerMethodName != null) {
+ item.setOnMenuItemClickListener(
+ new InflatedOnMenuItemClickListener(mContext, itemListenerMethodName));
+ }
- if (itemCheckable >= 2) {
+ if (itemCheckable >= 2 && item instanceof MenuItemImpl) {
((MenuItemImpl) item).setExclusiveCheckable(true);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index eca583f..c71f4bde 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2869,7 +2869,7 @@
*/
@ViewDebug.ExportedProperty(mapping = {
@ViewDebug.IntToString(from = PERSISTENT_NO_CACHE, to = "NONE"),
- @ViewDebug.IntToString(from = PERSISTENT_ALL_CACHES, to = "ANIMATION"),
+ @ViewDebug.IntToString(from = PERSISTENT_ANIMATION_CACHE, to = "ANIMATION"),
@ViewDebug.IntToString(from = PERSISTENT_SCROLLING_CACHE, to = "SCROLLING"),
@ViewDebug.IntToString(from = PERSISTENT_ALL_CACHES, to = "ALL")
})
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 7dd5085..e1ff4e8 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -61,6 +61,13 @@
@hide
*/
public static final int FEATURE_OPENGL = 8;
+ /**
+ * Flag for enabling the Action Bar.
+ * This is enabled by default for some devices. The Action Bar
+ * replaces the title bar and provides an alternate location
+ * for an on-screen menu button on some devices.
+ */
+ public static final int FEATURE_ACTION_BAR = 9;
/** Flag for setting the progress bar's visibility to VISIBLE */
public static final int PROGRESS_VISIBILITY_ON = -1;
/** Flag for setting the progress bar's visibility to GONE */
@@ -981,6 +988,16 @@
{
return mFeatures;
}
+
+ /**
+ * Query for the availability of a certain feature.
+ *
+ * @param feature The feature ID to check
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean hasFeature(int feature) {
+ return (getFeatures() & (1 << feature)) != 0;
+ }
/**
* Return the feature bits that are being implemented by this Window.
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 8af2492..0e0e032 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -542,6 +542,13 @@
int which) {
res.cancel();
}})
+ .setOnCancelListener(
+ new DialogInterface.OnCancelListener() {
+ public void onCancel(
+ DialogInterface dialog) {
+ res.cancel();
+ }
+ })
.show();
}
// Tell the JsResult that it is ready for client
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 38cfadb..e7517205 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3208,6 +3208,8 @@
// Send the click so that the textfield is in focus
centerKeyPressOnTextField();
rebuildWebTextView();
+ } else {
+ clearTextEntry(true);
}
if (inEditingMode()) {
return mWebTextView.performLongClick();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 64c9c99..968636b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2781,6 +2781,11 @@
c.drawText(mChars, start + mStart, end - start, x, y, p);
}
+ public void drawTextRun(Canvas c, int start, int end,
+ float x, float y, int flags, Paint p) {
+ c.drawTextRun(mChars, start + mStart, end - start, x, y, flags, p);
+ }
+
public float measureText(int start, int end, Paint p) {
return p.measureText(mChars, start + mStart, end - start);
}
diff --git a/core/java/com/android/internal/app/SplitActionBar.java b/core/java/com/android/internal/app/SplitActionBar.java
new file mode 100644
index 0000000..4e19e04
--- /dev/null
+++ b/core/java/com/android/internal/app/SplitActionBar.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.app.ActionBar;
+import android.graphics.drawable.Drawable;
+import android.view.ActionBarView;
+import android.view.View;
+import android.widget.LinearLayout;
+
+/**
+ * SplitActionBar is the ActionBar implementation used
+ * by small-screen devices. It expects to split contextual
+ * modes across both the ActionBarView at the top of the screen
+ * and a horizontal LinearLayout at the bottom which is normally
+ * hidden.
+ */
+public class SplitActionBar extends ActionBar {
+ private ActionBarView mActionView;
+ private LinearLayout mContextView;
+
+ public SplitActionBar(ActionBarView view, LinearLayout contextView) {
+ mActionView = view;
+ mContextView = contextView;
+ }
+
+ public void setCallback(Callback callback) {
+ mActionView.setCallback(callback);
+ }
+
+ public void setCustomNavigationView(View view) {
+ mActionView.setCustomNavigationView(view);
+ }
+
+ public void setTitle(CharSequence title) {
+ mActionView.setTitle(title);
+ }
+
+ public void setSubtitle(CharSequence subtitle) {
+ mActionView.setSubtitle(subtitle);
+ }
+
+ public void setNavigationMode(int mode) {
+ mActionView.setNavigationMode(mode);
+ }
+
+ public void setDisplayOptions(int options) {
+ mActionView.setDisplayOptions(options);
+ }
+
+ public void setBackgroundDrawable(Drawable d) {
+ mActionView.setBackgroundDrawable(d);
+ }
+
+ public void setDividerDrawable(Drawable d) {
+ mActionView.setDividerDrawable(d);
+ }
+
+ public View getCustomNavigationView() {
+ return mActionView.getCustomNavigationView();
+ }
+
+ public CharSequence getTitle() {
+ return mActionView.getTitle();
+ }
+
+ public CharSequence getSubtitle() {
+ return mActionView.getSubtitle();
+ }
+
+ public int getNavigationMode() {
+ return mActionView.getNavigationMode();
+ }
+
+ public int getDisplayOptions() {
+ return mActionView.getDisplayOptions();
+ }
+
+ public void updateActionMenu() {
+ mActionView.updateActionMenu();
+ }
+
+}
diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java
new file mode 100644
index 0000000..3d44ebc
--- /dev/null
+++ b/core/java/com/android/internal/view/menu/ActionMenu.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.view.menu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.SubMenu;
+
+/**
+ * @hide
+ */
+public class ActionMenu implements Menu {
+ private Context mContext;
+
+ private boolean mIsQwerty;
+
+ private ArrayList<ActionMenuItem> mItems;
+
+ public ActionMenu(Context context) {
+ mContext = context;
+ mItems = new ArrayList<ActionMenuItem>();
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public MenuItem add(CharSequence title) {
+ return add(0, 0, 0, title);
+ }
+
+ public MenuItem add(int titleRes) {
+ return add(0, 0, 0, titleRes);
+ }
+
+ public MenuItem add(int groupId, int itemId, int order, int titleRes) {
+ return add(groupId, itemId, order, mContext.getResources().getString(titleRes));
+ }
+
+ public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
+ ActionMenuItem item = new ActionMenuItem(getContext(),
+ groupId, itemId, 0, order, title);
+ mItems.add(order, item);
+ return item;
+ }
+
+ public int addIntentOptions(int groupId, int itemId, int order,
+ ComponentName caller, Intent[] specifics, Intent intent, int flags,
+ MenuItem[] outSpecificItems) {
+ PackageManager pm = mContext.getPackageManager();
+ final List<ResolveInfo> lri =
+ pm.queryIntentActivityOptions(caller, specifics, intent, 0);
+ final int N = lri != null ? lri.size() : 0;
+
+ if ((flags & FLAG_APPEND_TO_GROUP) == 0) {
+ removeGroup(groupId);
+ }
+
+ for (int i=0; i<N; i++) {
+ final ResolveInfo ri = lri.get(i);
+ Intent rintent = new Intent(
+ ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]);
+ rintent.setComponent(new ComponentName(
+ ri.activityInfo.applicationInfo.packageName,
+ ri.activityInfo.name));
+ final MenuItem item = add(groupId, itemId, order, ri.loadLabel(pm))
+ .setIcon(ri.loadIcon(pm))
+ .setIntent(rintent);
+ if (outSpecificItems != null && ri.specificIndex >= 0) {
+ outSpecificItems[ri.specificIndex] = item;
+ }
+ }
+
+ return N;
+ }
+
+ public SubMenu addSubMenu(CharSequence title) {
+ // TODO Implement submenus
+ return null;
+ }
+
+ public SubMenu addSubMenu(int titleRes) {
+ // TODO Implement submenus
+ return null;
+ }
+
+ public SubMenu addSubMenu(int groupId, int itemId, int order,
+ CharSequence title) {
+ // TODO Implement submenus
+ return null;
+ }
+
+ public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
+ // TODO Implement submenus
+ return null;
+ }
+
+ public void clear() {
+ mItems.clear();
+ }
+
+ public void close() {
+ }
+
+ private int findItemIndex(int id) {
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+ for (int i = 0; i < itemCount; i++) {
+ if (items.get(i).getItemId() == id) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public MenuItem findItem(int id) {
+ return mItems.get(findItemIndex(id));
+ }
+
+ public MenuItem getItem(int index) {
+ return mItems.get(index);
+ }
+
+ public boolean hasVisibleItems() {
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+
+ for (int i = 0; i < itemCount; i++) {
+ if (items.get(i).isVisible()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) {
+ // TODO Make this smarter.
+ final boolean qwerty = mIsQwerty;
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+
+ for (int i = 0; i < itemCount; i++) {
+ ActionMenuItem item = items.get(i);
+ final char shortcut = qwerty ? item.getAlphabeticShortcut() :
+ item.getNumericShortcut();
+ if (keyCode == shortcut) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+ public boolean isShortcutKey(int keyCode, KeyEvent event) {
+ return findItemWithShortcut(keyCode, event) != null;
+ }
+
+ public boolean performIdentifierAction(int id, int flags) {
+ final int index = findItemIndex(id);
+ if (index < 0) {
+ return false;
+ }
+
+ return mItems.get(index).invoke();
+ }
+
+ public boolean performShortcut(int keyCode, KeyEvent event, int flags) {
+ ActionMenuItem item = findItemWithShortcut(keyCode, event);
+ if (item == null) {
+ return false;
+ }
+
+ return item.invoke();
+ }
+
+ public void removeGroup(int groupId) {
+ final ArrayList<ActionMenuItem> items = mItems;
+ int itemCount = items.size();
+ int i = 0;
+ while (i < itemCount) {
+ if (items.get(i).getGroupId() == groupId) {
+ items.remove(i);
+ itemCount--;
+ } else {
+ i++;
+ }
+ }
+ }
+
+ public void removeItem(int id) {
+ mItems.remove(findItemIndex(id));
+ }
+
+ public void setGroupCheckable(int group, boolean checkable,
+ boolean exclusive) {
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+
+ for (int i = 0; i < itemCount; i++) {
+ ActionMenuItem item = items.get(i);
+ if (item.getGroupId() == group) {
+ item.setCheckable(checkable);
+ item.setExclusiveCheckable(exclusive);
+ }
+ }
+ }
+
+ public void setGroupEnabled(int group, boolean enabled) {
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+
+ for (int i = 0; i < itemCount; i++) {
+ ActionMenuItem item = items.get(i);
+ if (item.getGroupId() == group) {
+ item.setEnabled(enabled);
+ }
+ }
+ }
+
+ public void setGroupVisible(int group, boolean visible) {
+ final ArrayList<ActionMenuItem> items = mItems;
+ final int itemCount = items.size();
+
+ for (int i = 0; i < itemCount; i++) {
+ ActionMenuItem item = items.get(i);
+ if (item.getGroupId() == group) {
+ item.setVisible(visible);
+ }
+ }
+ }
+
+ public void setQwertyMode(boolean isQwerty) {
+ mIsQwerty = isQwerty;
+ }
+
+ public int size() {
+ return mItems.size();
+ }
+}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
new file mode 100644
index 0000000..47d5fb9
--- /dev/null
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.view.menu;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.view.MenuItem;
+import android.view.SubMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+
+/**
+ * @hide
+ */
+public class ActionMenuItem implements MenuItem {
+ private final int mId;
+ private final int mGroup;
+ private final int mCategoryOrder;
+ private final int mOrdering;
+
+ private CharSequence mTitle;
+ private CharSequence mTitleCondensed;
+ private Intent mIntent;
+ private char mShortcutNumericChar;
+ private char mShortcutAlphabeticChar;
+
+ private Drawable mIconDrawable;
+ private int mIconResId = NO_ICON;
+
+ private Context mContext;
+
+ private MenuItem.OnMenuItemClickListener mClickListener;
+
+ private static final int NO_ICON = 0;
+
+ private int mFlags = ENABLED;
+ private static final int CHECKABLE = 0x00000001;
+ private static final int CHECKED = 0x00000002;
+ private static final int EXCLUSIVE = 0x00000004;
+ private static final int HIDDEN = 0x00000008;
+ private static final int ENABLED = 0x00000010;
+
+ public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering,
+ CharSequence title) {
+ mContext = context;
+ mId = id;
+ mGroup = group;
+ mCategoryOrder = categoryOrder;
+ mOrdering = ordering;
+ mTitle = title;
+ }
+
+ public char getAlphabeticShortcut() {
+ return mShortcutAlphabeticChar;
+ }
+
+ public int getGroupId() {
+ return mGroup;
+ }
+
+ public Drawable getIcon() {
+ return mIconDrawable;
+ }
+
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ public int getItemId() {
+ return mId;
+ }
+
+ public ContextMenuInfo getMenuInfo() {
+ return null;
+ }
+
+ public char getNumericShortcut() {
+ return mShortcutNumericChar;
+ }
+
+ public int getOrder() {
+ return mOrdering;
+ }
+
+ public SubMenu getSubMenu() {
+ return null;
+ }
+
+ public CharSequence getTitle() {
+ return mTitle;
+ }
+
+ public CharSequence getTitleCondensed() {
+ return mTitleCondensed;
+ }
+
+ public boolean hasSubMenu() {
+ return false;
+ }
+
+ public boolean isCheckable() {
+ return (mFlags & CHECKABLE) != 0;
+ }
+
+ public boolean isChecked() {
+ return (mFlags & CHECKED) != 0;
+ }
+
+ public boolean isEnabled() {
+ return (mFlags & ENABLED) != 0;
+ }
+
+ public boolean isVisible() {
+ return (mFlags & HIDDEN) == 0;
+ }
+
+ public MenuItem setAlphabeticShortcut(char alphaChar) {
+ mShortcutAlphabeticChar = alphaChar;
+ return this;
+ }
+
+ public MenuItem setCheckable(boolean checkable) {
+ mFlags = (mFlags & ~CHECKABLE) | (checkable ? CHECKABLE : 0);
+ return this;
+ }
+
+ public ActionMenuItem setExclusiveCheckable(boolean exclusive) {
+ mFlags = (mFlags & ~EXCLUSIVE) | (exclusive ? EXCLUSIVE : 0);
+ return this;
+ }
+
+ public MenuItem setChecked(boolean checked) {
+ mFlags = (mFlags & ~CHECKED) | (checked ? CHECKED : 0);
+ return this;
+ }
+
+ public MenuItem setEnabled(boolean enabled) {
+ mFlags = (mFlags & ~ENABLED) | (enabled ? ENABLED : 0);
+ return this;
+ }
+
+ public MenuItem setIcon(Drawable icon) {
+ mIconDrawable = icon;
+ mIconResId = NO_ICON;
+ return this;
+ }
+
+ public MenuItem setIcon(int iconRes) {
+ mIconResId = iconRes;
+ mIconDrawable = mContext.getResources().getDrawable(iconRes);
+ return this;
+ }
+
+ public MenuItem setIntent(Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ public MenuItem setNumericShortcut(char numericChar) {
+ mShortcutNumericChar = numericChar;
+ return this;
+ }
+
+ public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener menuItemClickListener) {
+ mClickListener = menuItemClickListener;
+ return this;
+ }
+
+ public MenuItem setShortcut(char numericChar, char alphaChar) {
+ mShortcutNumericChar = numericChar;
+ mShortcutAlphabeticChar = alphaChar;
+ return this;
+ }
+
+ public MenuItem setTitle(CharSequence title) {
+ mTitle = title;
+ return this;
+ }
+
+ public MenuItem setTitle(int title) {
+ mTitle = mContext.getResources().getString(title);
+ return this;
+ }
+
+ public MenuItem setTitleCondensed(CharSequence title) {
+ mTitleCondensed = title;
+ return this;
+ }
+
+ public MenuItem setVisible(boolean visible) {
+ mFlags = (mFlags & HIDDEN) | (visible ? 0 : HIDDEN);
+ return this;
+ }
+
+ public boolean invoke() {
+ if (mClickListener != null && mClickListener.onMenuItemClick(this)) {
+ return true;
+ }
+
+ if (mIntent != null) {
+ mContext.startActivity(mIntent);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index dbbd286..56bc851 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -86,12 +86,20 @@
*/
public static final int MIN_PATTERN_REGISTER_FAIL = 3;
+ /**
+ * The number of previous password hashes to store. This is used to prevent
+ * the user from setting the same password as any of the stored ones.
+ */
+ public static final int MAX_PASSWORD_HISTORY_LENGTH = 5;
+
private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
private final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
private final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
+ private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
+
private final Context mContext;
private final ContentResolver mContentResolver;
private DevicePolicyManager mDevicePolicyManager;
@@ -202,8 +210,22 @@
}
/**
- * Checks to see if the given file exists and contains any data. Returns true if it does,
- * false otherwise.
+ * Check to see if a password matches any of the passwords stored in the
+ * password history.
+ *
+ * @param password The password to check.
+ * @return Whether the password matches any in the history.
+ */
+ public boolean checkPasswordHistory(String password) {
+ String passwordHashString = new String(passwordToHash(password));
+ String passwordHistory = getString(PASSWORD_HISTORY_KEY);
+ return passwordHistory != null && passwordHistory.contains(passwordHashString);
+ }
+
+ /**
+ * Checks to see if the given file exists and contains any data. Returns
+ * true if it does, false otherwise.
+ *
* @param filename
* @return true if file exists and is non-empty.
*/
@@ -384,6 +406,20 @@
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
}
+ // Add the password to the password history. We assume all
+ // password
+ // hashes have the same length for simplicity of implementation.
+ String passwordHistory = getString(PASSWORD_HISTORY_KEY);
+ if (passwordHistory == null) {
+ passwordHistory = new String();
+ }
+ passwordHistory = new String(hash) + "," + passwordHistory;
+ // Cut it to contain MAX_PASSWORD_HISTORY_LENGTH hashes
+ // and MAX_PASSWORD_HISTORY_LENGTH -1 commas.
+ passwordHistory = passwordHistory.substring(0, Math.min(hash.length
+ * MAX_PASSWORD_HISTORY_LENGTH + MAX_PASSWORD_HISTORY_LENGTH - 1,
+ passwordHistory.length()));
+ setString(PASSWORD_HISTORY_KEY, passwordHistory);
} else {
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
@@ -650,6 +686,14 @@
android.provider.Settings.Secure.putLong(mContentResolver, secureSettingKey, value);
}
+ private String getString(String secureSettingKey) {
+ return android.provider.Settings.Secure.getString(mContentResolver, secureSettingKey);
+ }
+
+ private void setString(String secureSettingKey, String value) {
+ android.provider.Settings.Secure.putString(mContentResolver, secureSettingKey, value);
+ }
+
public boolean isSecure() {
long mode = getKeyguardStoredPasswordQuality();
final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index e1e9536..4c7e762 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -30,6 +30,8 @@
#include "SkBoundaryPatch.h"
#include "SkMeshUtils.h"
+#include "unicode/ubidi.h"
+
#define TIME_DRAWx
static uint32_t get_thread_msec() {
@@ -52,6 +54,24 @@
class SkCanvasGlue {
public:
+ enum {
+ kDirection_LTR = 0,
+ kDirection_RTL = 1
+ };
+
+ enum {
+ kDirection_Mask = 0x1
+ };
+
+ enum {
+ kBidi_LTR = 0,
+ kBidi_RTL = 1,
+ kBidi_Default_LTR = 2,
+ kBidi_Default_RTL = 3,
+ kBidi_Force_LTR = 4,
+ kBidi_Force_RTL = 5
+ };
+
static void finalizer(JNIEnv* env, jobject clazz, SkCanvas* canvas) {
canvas->unref();
}
@@ -743,45 +763,206 @@
canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL,
indices, indexCount, *paint);
}
-
- static void drawText___CIIFFPaint(JNIEnv* env, jobject, SkCanvas* canvas,
- jcharArray text, int index, int count,
- jfloat x, jfloat y, SkPaint* paint) {
- jchar* textArray = env->GetCharArrayElements(text, NULL);
- jsize textCount = env->GetArrayLength(text);
+
+ static void shapeRtlText__(const jchar* text, jsize len, jsize start, jsize count, jchar* shaped) {
+ // fake shaping, just reverse the text
+ for (int i = 0; i < count; ++i) {
+ shaped[i] = text[start + count - 1 - i];
+ }
+ // fix surrogate pairs, if any
+ for (int i = 1; i < count; ++i) {
+ if (shaped[i] >= 0xd800 && shaped[i] < 0xdc00 &&
+ shaped[i-1] >= 0xdc00 && shaped[i-1] < 0xe000) {
+ jchar c = shaped[i]; shaped[i] = shaped[i-1]; shaped[i-1] = c;
+ i += 1;
+ }
+ }
+ }
+
+ static void drawText__(JNIEnv* env, SkCanvas* canvas, const jchar* text, jsize len,
+ jfloat x, jfloat y, int flags, SkPaint* paint) {
SkScalar x_ = SkFloatToScalar(x);
SkScalar y_ = SkFloatToScalar(y);
- canvas->drawText(textArray + index, count << 1, x_, y_, *paint);
- env->ReleaseCharArrayElements(text, textArray, 0);
+
+ SkPaint::Align horiz = paint->getTextAlign();
+
+ bool needBidi = (flags == kBidi_RTL) || (flags == kBidi_Default_RTL);
+ if (!needBidi && flags < kBidi_Force_LTR) {
+ for (int i = 0; i < len; ++i) {
+ if (text[i] >= 0x0590) {
+ needBidi = TRUE;
+ break;
+ }
+ }
+ }
+
+ int dir = (flags == kBidi_Force_RTL) ? kDirection_RTL : kDirection_LTR; // will be reset if we run bidi
+ UErrorCode status = U_ZERO_ERROR;
+ jchar *shaped = NULL;
+ int32_t slen = 0;
+ if (needBidi || (flags == kBidi_Force_RTL)) {
+ shaped = (jchar *)malloc(len * sizeof(jchar));
+ if (!shaped) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ if (needBidi) {
+ static int RTL_OPTS = UBIDI_DO_MIRRORING | UBIDI_KEEP_BASE_COMBINING |
+ UBIDI_REMOVE_BIDI_CONTROLS | UBIDI_OUTPUT_REVERSE;
+ jint lineDir = 0;
+ switch (flags) {
+ case kBidi_LTR: lineDir = 0; break; // no ICU constant, canonical LTR level
+ case kBidi_RTL: lineDir = 1; break; // no ICU constant, canonical RTL level
+ case kBidi_Default_LTR: lineDir = UBIDI_DEFAULT_LTR; break;
+ case kBidi_Default_RTL: lineDir = UBIDI_DEFAULT_RTL; break;
+ }
+
+ UBiDi* bidi = ubidi_open();
+ ubidi_setPara(bidi, text, len, lineDir, NULL, &status);
+ if (U_SUCCESS(status)) {
+ dir = ubidi_getParaLevel(bidi) & 0x1;
+
+ int rc = ubidi_countRuns(bidi, &status);
+ if (U_SUCCESS(status)) {
+ int32_t start;
+ int32_t length;
+ UBiDiDirection dir;
+ jchar *buffer = NULL;
+ for (int i = 0; i < rc; ++i) {
+ dir = ubidi_getVisualRun(bidi, i, &start, &length);
+ // fake shaping, except it doesn't shape, just mirrors and reverses
+ // use harfbuzz when available
+ if (dir == UBIDI_RTL) {
+ slen += ubidi_writeReverse(text + start, length, shaped + slen,
+ length, RTL_OPTS, &status);
+ } else {
+ for (int i = 0; i < length; ++i) {
+ shaped[slen + i] = text[start + i];
+ }
+ slen += length;
+ }
+ }
+ }
+ ubidi_close(bidi);
+ }
+ } else {
+ shapeRtlText__(text, len, 0, len, shaped);
+ }
+ }
+ }
+
+ if (!U_SUCCESS(status)) {
+ char buffer[35];
+ sprintf(buffer, "DrawText bidi error %d", status);
+ doThrowIAE(env, buffer);
+ } else {
+ bool trimLeft = false;
+ bool trimRight = false;
+
+ switch (horiz) {
+ case SkPaint::kLeft_Align: trimLeft = dir & kDirection_Mask; break;
+ case SkPaint::kCenter_Align: trimLeft = trimRight = true; break;
+ case SkPaint::kRight_Align: trimRight = !(dir & kDirection_Mask);
+ default: break;
+ }
+ const jchar* workText = shaped ? shaped : text;
+ const jchar* workLimit = workText + len;
+
+ if (trimLeft) {
+ while (workText < workLimit && *workText == ' ') {
+ ++workText;
+ }
+ }
+ if (trimRight) {
+ while (workLimit > workText && *(workLimit - 1) == ' ') {
+ --workLimit;
+ }
+ }
+ int32_t workBytes = (workLimit - workText) << 1;
+
+ canvas->drawText(workText, workBytes, x_, y_, *paint);
+ }
+
+ if (shaped) {
+ free(shaped);
+ }
+ }
+
+ static void drawText___CIIFFIPaint(JNIEnv* env, jobject, SkCanvas* canvas,
+ jcharArray text, int index, int count,
+ jfloat x, jfloat y, int flags, SkPaint* paint) {
+ jchar* textArray = env->GetCharArrayElements(text, NULL);
+ drawText__(env, canvas, textArray + index, count, x, y, flags, paint);
+ env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
}
- static void drawText__StringIIFFPaint(JNIEnv* env, jobject,
- SkCanvas* canvas, jstring text, int start, int end,
- jfloat x, jfloat y, SkPaint* paint) {
- const void* text_ = env->GetStringChars(text, NULL);
+ static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
+ SkCanvas* canvas, jstring text,
+ int start, int end,
+ jfloat x, jfloat y, int flags, SkPaint* paint) {
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ drawText__(env, canvas, textArray + start, end - start, x, y, flags, paint);
+ env->ReleaseStringChars(text, textArray);
+ }
+
+ // Draws a unidirectional run of text. Does not run bidi, but does reorder the
+ // text and run shaping (or will, when we have harfbuzz support).
+ static void drawTextRun__(JNIEnv* env, SkCanvas* canvas, const jchar* chars, int len,
+ int start, int count,
+ jfloat x, jfloat y, int flags, SkPaint* paint) {
+
SkScalar x_ = SkFloatToScalar(x);
SkScalar y_ = SkFloatToScalar(y);
- canvas->drawText((const uint16_t*)text_ + start, (end - start) << 1,
- x_, y_, *paint);
- env->ReleaseStringChars(text, (const jchar*) text_);
- }
-
- static void drawString(JNIEnv* env, jobject canvas, jstring text,
- jfloat x, jfloat y, jobject paint) {
- NPE_CHECK_RETURN_VOID(env, canvas);
- NPE_CHECK_RETURN_VOID(env, paint);
- NPE_CHECK_RETURN_VOID(env, text);
- size_t count = env->GetStringLength(text);
- if (0 == count) {
- return;
+
+ uint8_t rtl = flags & 0x1;
+
+ UErrorCode status = U_ZERO_ERROR;
+ jchar *shaped = NULL;
+ if (rtl) {
+ shaped = (jchar *)malloc(count * sizeof(jchar));
+ if (!shaped) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ shapeRtlText__(chars, len, start, count, shaped);
+ }
}
- const jchar* text_ = env->GetStringChars(text, NULL);
- SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas);
- c->drawText(text_, count << 1, SkFloatToScalar(x), SkFloatToScalar(y),
- *GraphicsJNI::getNativePaint(env, paint));
- env->ReleaseStringChars(text, text_);
+
+ if (!U_SUCCESS(status)) {
+ char buffer[30];
+ sprintf(buffer, "DrawTextRun error %d", status);
+ doThrowIAE(env, buffer);
+ } else {
+ if (shaped) {
+ canvas->drawText(shaped, count << 1, x_, y_, *paint);
+ } else {
+ canvas->drawText(chars + start, count << 1, x_, y_, *paint);
+ }
+ }
+
+ if (shaped) {
+ free(shaped);
+ }
}
-
+
+ static void drawTextRun___CIIFFIPaint(
+ JNIEnv* env, jobject, SkCanvas* canvas, jcharArray text, int index,
+ int count, jfloat x, jfloat y, int flags, SkPaint* paint) {
+
+ jint len = env->GetArrayLength(text);
+ jchar* chars = env->GetCharArrayElements(text, NULL);
+ drawTextRun__(env, canvas, chars, len, index, count, x, y, flags, paint);
+ env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
+ }
+
+ static void drawTextRun__StringIIFFIPaint(
+ JNIEnv* env, jobject obj, SkCanvas* canvas, jstring text, int start,
+ int end, jfloat x, jfloat y, int flags, SkPaint* paint) {
+
+ jint len = env->GetStringLength(text);
+ const jchar* chars = env->GetStringChars(text, NULL);
+ drawTextRun__(env, canvas, chars, len, start, end - start, x, y, flags, paint);
+ env->ReleaseStringChars(text, chars);
+ }
+
static void drawPosText___CII_FPaint(JNIEnv* env, jobject, SkCanvas* canvas,
jcharArray text, int index, int count,
jfloatArray pos, SkPaint* paint) {
@@ -947,12 +1128,14 @@
(void*)SkCanvasGlue::drawBitmapMesh},
{"nativeDrawVertices", "(III[FI[FI[II[SIII)V",
(void*)SkCanvasGlue::drawVertices},
- {"native_drawText","(I[CIIFFI)V",
- (void*) SkCanvasGlue::drawText___CIIFFPaint},
- {"native_drawText","(ILjava/lang/String;IIFFI)V",
- (void*) SkCanvasGlue::drawText__StringIIFFPaint},
- {"drawText","(Ljava/lang/String;FFLandroid/graphics/Paint;)V",
- (void*) SkCanvasGlue::drawString},
+ {"native_drawText","(I[CIIFFII)V",
+ (void*) SkCanvasGlue::drawText___CIIFFIPaint},
+ {"native_drawText","(ILjava/lang/String;IIFFII)V",
+ (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
+ {"native_drawTextRun","(I[CIIFFII)V",
+ (void*) SkCanvasGlue::drawTextRun___CIIFFIPaint},
+ {"native_drawTextRun","(ILjava/lang/String;IIFFII)V",
+ (void*) SkCanvasGlue::drawTextRun__StringIIFFIPaint},
{"native_drawPosText","(I[CII[FI)V",
(void*) SkCanvasGlue::drawPosText___CII_FPaint},
{"native_drawPosText","(ILjava/lang/String;[FI)V",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ccfeae3..216c387 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1233,12 +1233,12 @@
android:description="@string/permlab_copyProtectedData"
android:protectionLevel="signature" />
- <!-- Push messaging permission.
+ <!-- C2DM permission.
@hide Used internally.
-->
- <permission android:name="android.intent.category.MASTER_CLEAR.permission.PUSH_MESSAGE"
+ <permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
- <uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.PUSH_MESSAGE"/>
+ <uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.C2D_MESSAGE"/>
<application android:process="system"
android:persistent="true"
@@ -1322,7 +1322,7 @@
<action android:name="android.intent.action.MASTER_CLEAR" />
<!-- MCS always uses REMOTE_INTENT: category=MASTER_CLEAR -->
- <action android:name="com.google.android.pushmessaging.intent.RECEIVE" />
+ <action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="android.intent.category.MASTER_CLEAR" />
</intent-filter>
</receiver>
diff --git a/core/res/res/drawable/action_bar_background.xml b/core/res/res/drawable/action_bar_background.xml
new file mode 100644
index 0000000..3929d7f
--- /dev/null
+++ b/core/res/res/drawable/action_bar_background.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:startColor="#ffd1d2d4"
+ android:endColor="#ff85878a"
+ android:angle="270" />
+</shape>
diff --git a/core/res/res/drawable/action_bar_divider.xml b/core/res/res/drawable/action_bar_divider.xml
new file mode 100644
index 0000000..414309f
--- /dev/null
+++ b/core/res/res/drawable/action_bar_divider.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <gradient
+ android:startColor="#ffe1e2e4"
+ android:endColor="#ff95979a"
+ android:angle="270" />
+</shape>
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
new file mode 100644
index 0000000..d7f7c13
--- /dev/null
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAppearance="?android:attr/textAppearanceMediumInverse" />
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
new file mode 100644
index 0000000..01a4b42
--- /dev/null
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+This is an optimized layout for a screen with the Action Bar enabled.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:fitsSystemWindows="true">
+ <ActionBarView android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/windowActionBarStyle" />
+ <FrameLayout android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:foregroundGravity="fill_horizontal|top"
+ android:foreground="?android:attr/windowContentOverlay" />
+ <LinearLayout android:id="@+id/context_action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/windowActionBarStyle"
+ android:visibility="gone" />
+</LinearLayout>
+
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1449b02..e7b83c7 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -244,6 +244,13 @@
{@link android.R.styleable#WindowAnimation}. -->
<attr name="windowAnimationStyle" format="reference" />
+ <!-- Flag indicating whether this window should have an Action Bar
+ in place of the usual title bar. -->
+ <attr name="windowActionBar" format="boolean" />
+
+ <!-- Reference to a style for the Action Bar -->
+ <attr name="windowActionBarStyle" format="reference" />
+
<!-- Defines the default soft input state that this window would
like when it is displayed. -->
<attr name="windowSoftInputMode">
@@ -948,6 +955,8 @@
<attr name="textColor" />
<attr name="backgroundDimEnabled" />
<attr name="backgroundDimAmount" />
+ <attr name="windowActionBar" />
+ <attr name="windowActionBarStyle" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
@@ -3243,6 +3252,10 @@
<!-- Whether the item is enabled. -->
<attr name="enabled" />
+ <!-- Name of a method on the Context used to inflate the menu that will be
+ called when the item is clicked. -->
+ <attr name="onClick" />
+
</declare-styleable>
<!-- **************************************************************** -->
@@ -3762,4 +3775,42 @@
<attr name="withClass" format="string" />
</declare-styleable>
+ <!-- Attributes used to style the Action Bar. -->
+ <declare-styleable name="ActionBar">
+ <!-- The type of navigation to use. -->
+ <attr name="navigationMode">
+ <!-- Normal static title text -->
+ <enum name="normal" value="0" />
+ <!-- The action bar will use a drop-down selection in place of title text. -->
+ <enum name="dropdownList" value="1" />
+ <!-- The action bar will use a series of horizontal tabs in place of title text. -->
+ <enum name="tabBar" value="2" />
+ </attr>
+ <!-- Options affecting how the action bar is displayed. -->
+ <attr name="displayOptions">
+ <flag name="useLogo" value="1" />
+ <flag name="hideHome" value="2" />
+ </attr>
+ <!-- Specifies the color used to style the action bar. -->
+ <attr name="colorFilter" format="color" />
+ <!-- Specifies title text used for navigationMode="normal" -->
+ <attr name="title" />
+ <!-- Specifies subtitle text used for navigationMode="normal" -->
+ <attr name="subtitle" format="string" />
+ <!-- Specifies a style to use for title text. -->
+ <attr name="titleTextStyle" format="reference" />
+ <!-- Specifies a style to use for subtitle text. -->
+ <attr name="subtitleTextStyle" format="reference" />
+ <!-- Specifies the drawable used for the application icon. -->
+ <attr name="icon" />
+ <!-- Specifies the drawable used for the application logo. -->
+ <attr name="logo" />
+ <!-- Specifies the drawable used for item dividers. -->
+ <attr name="divider" />
+ <!-- Specifies a background drawable for the action bar. -->
+ <attr name="background" />
+ <!-- Specifies a layout for custom navigation. Overrides navigationMode. -->
+ <attr name="customNavigationLayout" format="reference" />
+ </declare-styleable>
+
</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 8b6af71..e607fad5 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -68,4 +68,5 @@
<item type="id" name="accountPreferences" />
<item type="id" name="smallIcon" />
<item type="id" name="custom" />
+ <item type="id" name="home" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index fe27174..9055970 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1275,5 +1275,15 @@
<public type="attr" name="withExpression" />
<public type="attr" name="withClass" />
<public type="attr" name="allContactsName" />
+ <public type="attr" name="windowActionBar" />
+ <public type="attr" name="windowActionBarStyle" />
+ <public type="attr" name="navigationMode" />
+ <public type="attr" name="displayOptions" />
+ <public type="attr" name="subtitle" />
+ <public type="attr" name="customNavigationLayout" />
+
+ <public type="id" name="home" />
+
+ <public type="style" name="Theme.WithActionBar" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 96d30a3..870770f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -60,6 +60,10 @@
<!-- Displayed when the user dialed an MMI code whose function
could not be performed. This will be displayed in a toast. -->
<string name="mmiError">Connection problem or invalid MMI code.</string>
+ <!-- Displayed when the user dialed an MMI code whose function
+ could not be performed because FDN is enabled. This will be displayed in a toast. -->
+ <string name="mmiFdnError">Operation is restricted to fixed dialing numbers only.</string>
+
<!-- Displayed when a phone feature such as call barring was activated. -->
<string name="serviceEnabled">Service was enabled.</string>
<!-- Displayed in front of the list of a set of service classes
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f9b0667..73c3444 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -840,4 +840,10 @@
<item name="android:paddingBottom">1dip</item>
<item name="android:background">@android:drawable/bottom_bar</item>
</style>
+
+ <style name="ActionBar">
+ <item name="android:background">@android:drawable/action_bar_background</item>
+ <item name="android:displayOptions">useLogo</item>
+ <item name="android:divider">@android:drawable/action_bar_divider</item>
+ </style>
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d585d9e..32c5f47 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -115,6 +115,8 @@
<item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+ <item name="windowActionBar">false</item>
+ <item name="windowActionBarStyle">@android:style/ActionBar</item>
<!-- Dialog attributes -->
<item name="alertDialogStyle">@android:style/AlertDialog</item>
@@ -521,5 +523,9 @@
<item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
<item name="android:textColor">@android:color/secondary_text_nofocus</item>
</style>
+
+ <style name="Theme.WithActionBar">
+ <item name="android:windowActionBar">true</item>
+ </style>
</resources>
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 398d863..c5112f6 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -83,6 +83,7 @@
<table>
<tr><th>Platform Version</th><th>API Level</th></tr>
+ <tr><td>Android 2.2</td><td>8</td></tr>
<tr><td>Android 2.1</td><td>7</td></tr>
<tr><td>Android 2.0.1</td><td>6</td></tr>
<tr><td>Android 2.0</td><td>5</td></tr>
diff --git a/docs/html/guide/appendix/install-location.jd b/docs/html/guide/appendix/install-location.jd
new file mode 100644
index 0000000..be89caf
--- /dev/null
+++ b/docs/html/guide/appendix/install-location.jd
@@ -0,0 +1,197 @@
+page.title=App Install Location
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Quickview</h2>
+ <ul>
+ <li>You can allow your application to install on the device's external storage.</li>
+ <li>Some types of applications should <strong>not</strong> allow installation on the external
+storage.</li>
+ <li>Installing on the external storage is ideal for large applications that are not tightly
+integrated with the system (most commonly, games).</li>
+ </ul>
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#Compatiblity">Backward Compatibility</a></li>
+ <li><a href="#ShouldNot">Applications That Should NOT Install on External Storage</a></li>
+ <li><a href="#Should">Applications That Should Install on External Storage</a></li>
+ </ol>
+
+ <h2>See also</h2>
+ <ol>
+ <li><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">
+<manifest></a></code></li>
+ </ol>
+
+</div>
+</div>
+
+<p>Beginning with API Level 8, you can allow your application to be installed on the
+external storage (for example, the device's SD card). This is an optional feature you can declare
+for your application with the <a
+href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> manifest attribute. If you do
+<em>not</em> declare this attribute, your application will be installed on the internal storage
+only and it cannot be moved to the external storage.</p>
+
+<p>To allow the system to install your application on the external storage, modify your
+manifest file to include the <a
+href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> attribute in the <code><a
+href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> element,
+with a value of either "{@code preferExternal}" or "{@code auto}". For example:</p>
+
+<pre>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:installLocation="preferExternal"
+ ... >
+</pre>
+
+<p>If you declare "{@code preferExternal}", you request that your application be installed on the
+external storage, but the system does not guarantee that your application will be installed on
+the external storage. If the external storage is full, the system will install it on the internal
+storage. The user can also move your application between the two locations.</p>
+
+<p>If you declare "{@code auto}", you indicate that your application may be installed on the
+external storage, but you don't have a preference of install location. The system will
+decide where to install your application based on several factors. The user can also move your
+application between the two locations.</p>
+
+<p>When your application is installed on the external storage:</p>
+<ul>
+ <li>There is no effect on the application performance so long
+as the external storage is mounted on the device.</li>
+ <li>The {@code .apk} file is saved on the external storage, but all private user data,
+databases, optimized {@code .dex} files, and extracted native code are saved on the
+internal device memory.</li>
+ <li>The unique container in which your application is stored is encrypted with a randomly
+generated key that can be decrypted only by the device that originally installed it. Thus, an
+application installed on an SD card works for only one device.</li>
+ <li>The user can move your application to the internal storage through the system settings.</li>
+</ul>
+
+<p class="warning"><strong>Warning:</strong> When the user enables USB mass storage to share files
+with a computer or unmounts the SD card via the system settings, the external storage is unmounted
+from the device and all applications running on the external storage are immediately killed.</p>
+
+
+
+<h2 id="Compatiblity">Backward Compatibility</h2>
+
+<p>The ability for your application to install on the external storage is a feature available only
+on devices running API Level 8 (Android 2.2) or greater. Existing applications that were built prior
+to API Level 8 will always install on the internal storage and cannot be moved to the external
+storage (even on devices with API Level 8). However, if your application is designed to support an
+API Level <em>lower than</em> 8, you can choose to support this feature for devices with API Level 8
+or greater and still be compatible with devices using an API Level lower than 8.</p>
+
+<p>To allow installation on external storage and remain compatible with versions lower than API
+Level 8:</p>
+<ol>
+ <li>Include the {@code android:installLocation} attribute with a value of "{@code auto}" or
+"{@code preferExternal}" in the <code><a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><manifest></a></code>
+element.</li>
+ <li>Leave your {@code android:minSdkVersion} attribute as is (something <em>less
+than</em> "8") and be certain that your application code uses only APIs compatible with that
+level.</li>
+ <li>In order to compile your application, change your build target to API Level 8. This is
+necessary because older Android libraries don't understand the {@code android:installLocation}
+attribute and will not compile your application when it's present.</li>
+</ol>
+
+<p>When your application is installed on a device with an API Level lower than 8, the {@code
+android:installLocation} attribute is ignored and the application is installed on the internal
+storage.</p>
+
+<p class="caution"><strong>Caution:</strong> Although XML markup such as this will be ignored by
+older platforms, you must be careful not to use programming APIs introduced in API Level 8
+while your {@code minSdkVersion} is less than "8", unless you perform the work necessary to
+provide backward compatiblity in your code. For information about building
+backward compatibility in your application code, see the <a
+href="{@docRoot}resources/articles/backward-compatibility.html">Backward Compatibility</a>
+article.</p>
+
+
+
+<h2 id="ShouldNot">Applications That Should NOT Install on External Storage</h2>
+
+<p>When the user enables USB mass storage to share files with their computer (or otherwise
+unmounts or removes the external storage), any application
+installed on the external storage and currently running is killed. The system effectively becomes
+unaware of the application until mass storage is disabled and the external storage is
+remounted on the device. Besides killing the application and making it unavailable to the user,
+this can break some types of applications in a more serious way. In order for your application to
+consistently behave as expected, you <strong>should not</strong> allow your application to be
+installed on the external storage if it uses any of the following features, due to the cited
+consequences when the external storage is unmounted:</p>
+
+<dl>
+ <dt>Services</dt>
+ <dd>Your running {@link android.app.Service} will be killed and will not be restarted when
+external storage is remounted. You can, however, register for the {@link
+android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE} broadcast Intent, which will notify
+your application when applications installed on external storage have become available to the
+system again. At which time, you can restart your Service.</dd>
+ <dt>Alarm Services</dt>
+ <dd>Your alarms registered with {@link android.app.AlarmManager} will be cancelled. You must
+manually re-register any alarms when external storage is remounted.</dd>
+ <dt>Input Method Engines</dt>
+ <dd>Your <a href="{@docRoot}resources/articles/on-screen-inputs.html">IME</a> will be
+replaced by the default IME. When external storage is remounted, the user can open system settings
+to enable your IME again.</dd>
+ <dt>Live Wallpapers</dt>
+ <dd>Your running <a href="{@docRoot}resources/articles/live-wallpapers.html">Live Wallpaper</a>
+will be replaced by the default Live Wallpaper. When external storage is remounted, the user can
+select your Live Wallpaper again.</dd>
+ <dt>Live Folders</dt>
+ <dd>Your <a href="{@docRoot}resources/articles/live-folders.html">Live Folder</a> will be
+removed from the home screen. When external storage is remounted, the user can add your Live Folder
+to the home screen again.</dd>
+ <dt>App Widgets</dt>
+ <dd>Your <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widget</a> will be removed
+from the home screen. When external storage is remounted, your App Widget will <em>not</em> be
+available for the user to select until the system resets the home application (usually not until a
+system reboot).</dd>
+ <dt>Account Managers</dt>
+ <dd>Your accounts created with {@link android.accounts.AccountManager} will disappear until
+external storage is remounted.</dd>
+ <dt>Sync Adapters</dt>
+ <dd>Your {@link android.content.AbstractThreadedSyncAdapter} and all its sync functionality will
+not work until external storage is remounted.</dd>
+ <dt>Device Administrators</dt>
+ <dd>Your {@link android.app.admin.DeviceAdminReceiver} and all its admin capabilities will
+be disabled, which can have unforeseeable consequences for the device functionality, which may
+persist after external storage is remounted.</dd>
+</dl>
+
+<p>If your application uses any of the features listed above, you <strong>should not</strong> allow
+your application to install on external storage. By default, the system <em>will not</em> allow your
+application to install on the external storage, so you don't need to worry about your existing
+applications. However, if you're certain that your application should never be installed on the
+external storage, then you should make this clear by declaring <a
+href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code
+android:installLocation}</a> with a value of "{@code internalOnly}". Though this does not
+change the default behavior, it explicitly states that your application should only be installed
+on the internal storage and serves as a reminder to you and other developers that this decision has
+been made.</p>
+
+
+<h2 id="Should">Applications That Should Install on External Storage</h2>
+
+<p>In simple terms, anything that does not use the features listed in the previous section
+are safe when installed on external storage. Large games are more commonly the types of
+applications that should allow installation on external storage, because games don't typically
+provide additional services when innactive. When external storage becomes unavailable and a game
+process is killed, there should be no visible effect when the storage becomes available again and
+the user restarts the game (assuming that the game properly saved its state during the normal
+<a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Activity lifecycle</a>).</p>
+
+<p>If your application requires several megabytes for the APK file, you should
+carefully consider whether to enable the application to install on the external storage so that
+users can preserve space on their internal storage.</p>
+
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 0b1afae..201a142 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -126,7 +126,7 @@
<p>This behavior is especially significant for applications that set their
<code><a
-href="@docRoot}guide/topics/manifest/uses-sdk-element.html">android:
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">android:
minSdkVersion</a></code> to 3 or lower, since Market will filter them from
small-screen devices by default. Such applications can enable support for
small-screen devices by adding a <code>android:targetSdkVersion="4"</code>
@@ -164,7 +164,7 @@
<p>For more information on how to declare support for screen sizes in your
application, see <code><a
href="{@docRoot}guide/topics/manifest/supports-screens-element.html"><supports-screens></a></code>
- and <a href="{@docRoot}guide/practices/screens-support.html">Supporting Multiple
+ and <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a>.</p>
</td>
</tr>
diff --git a/docs/html/guide/developing/testing/testing_otheride.jd b/docs/html/guide/developing/testing/testing_otheride.jd
index a76c5b8..2bdf4d0 100644
--- a/docs/html/guide/developing/testing/testing_otheride.jd
+++ b/docs/html/guide/developing/testing/testing_otheride.jd
@@ -68,9 +68,9 @@
which provides an overview of Android testing.
</p>
<p>
- If you are using Eclipse with ADT, the best way to test the application is to use Eclipse with ADT
- as well. To learn about this, please read the document <a
- href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
+ If you are developing in Eclipse with ADT, you can set up and run your tests
+directly in Eclipse. For more information, please read <a
+ href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
</p>
<h2 id="CreateTestProjectCommand">Working with Test Projects</h2>
<p>
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index dbfc8ef..6363ab2 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -7,7 +7,7 @@
that runs on your computer. The emulator lets you prototype, develop, and test
Android applications without using a physical device. </p>
-<p>The Android emulator all of the hardware and software features
+<p>The Android emulator mimics all of the hardware and software features
of a typical mobile device, except that it can not receive or place actual phone
calls. It provides a variety of navigation and control keys, which you can "press"
using your mouse or keyboard to generate events for your application. It also
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 2277501..3d356ae 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -77,9 +77,19 @@
<li><a href="<?cs var:toroot ?>guide/topics/ui/ui-events.html">
<span class="en">Handling UI Events</span>
</a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
<span class="en">Notifying the User</span>
+ </a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/toasts.html">
+ <span class="en">Creating Toast Notifications</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/notifications.html">
+ <span class="en">Creating Status Bar Notifications</span>
+ </a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/themes.html">
<span class="en">Applying Styles and Themes</span>
</a></li>
@@ -100,7 +110,7 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/resources/index.html">
<span class="en">Application Resources</span>
- </a></div>
+ </a> <span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/resources/providing-resources.html">
<span class="en">Providing Resources</span>
@@ -110,14 +120,14 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/runtime-changes.html">
<span class="en">Handling Runtime Changes</span>
- </a></li>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/localization.html">
<span class="en">Localization</span>
</a></li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/resources/available-resources.html">
<span class="en">Resource Types</span>
- </a></div>
+ </a> <span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/resources/animation-resource.html">Animation</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/resources/color-list-resource.html">Color State List</a></li>
@@ -431,8 +441,11 @@
<span class="en">Android API Levels</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/market-filters.html">
- <span class="en">Market Filters </span>
- </a><span class="new">new!</span></li>
+ <span class="en">Market Filters</span>
+ </a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>guide/appendix/install-location.html">
+ <span class="en">App Install Location</span>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
<span class="en">Supported Media Formats</span>
</a></li>
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 5e61e6c..1e254f0 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -169,8 +169,12 @@
or density resources, based on the generalized size or density of the current
device screen, and adapts them to the actual pixel map of the screen.</p>
-<p>The range of screens supported by Android and the generalized screen
-configurations that the platform maps them to are shown in the table below. </p>
+<p>The table below lists some of the more common screens supported
+by Android and illustrates how the platform maps them to generalized screen
+configurations.</p>
+
+<p class="table-caption" id="screens-table"><strong>Table 1.</strong> Examples of
+device screens supported by Android.</p>
<table id="screens-table" width="80%" style="margin-top:2em;">
<tbody>
@@ -236,15 +240,13 @@
</tbody>
</table>
-<p class="caption" style="margin-top:1em;margin-bottom:1.5em;"><strong>Table
-1.</strong> Summary of device screens supported by Android. </p>
+<p class="caption" style="margin-top:1em;margin-bottom:1.5em;"> </p>
<p>As shown above, the various screen configurations are arranged around a
-baseline screen — HVGA (320x480) resolution on a 3.2" screen — which
-is assigned a size of "normal" and a density of "medium". The HVGA screen is
-used as the baseline because all applications written against Android 1.5 or
-earlier are (by definition) written for the HVGA screen used on the T-Mobile G1
-and similar devices.</p>
+<em>baseline screen</em> that is assigned a size of "normal" and a density of
+"medium". The HVGA screen is used as the baseline because all applications
+written against Android 1.5 or earlier are (by definition) written for the HVGA
+screen used on the T-Mobile G1 and similar devices.</p>
<!-- <p>Note that each screen configuration spans a range of actual resolutions
and physical screen sizes. For example, the The baseline configuration spans a
@@ -267,6 +269,11 @@
properly implemented. For more information, see <a
href="#screen-independence">Best Practices for Screen Independence</a>.</p>
+<!--
+<p>For an overview of the relative numbers of high (hdpi), medium (mdpi), and
+low (ldpi) density screens, see the <a
+href="{@docRoot}guide/resources/dashboard/screen-densities.html">Screen Densities dashboard</a>.</p>
+-->
<h3 id="support">How Android supports multiple screens</h3>
@@ -401,7 +408,7 @@
display properly on most devices, especially when the device's screen is at the
baseline "normal" size or larger. </p>
-<p>However, note that applications written for the baseline HVGA screen may need
+<p>However, note that applications written for the baseline screen may need
minor adjustments before they display properly on smaller screens such as QVGA.
With the reduced screen area of small screens, there may be tradeoffs in design,
content, and function that you, as the application developer, need to consider.
@@ -557,7 +564,7 @@
<li>If you declare <code>largeScreens="false"</code>, your application can
still be installed by users of devices with large screens. When run on a device
with a large screen, this attribute value causes the platform to run the
-application in compatibility mode, rendering it in a baseline HVGA screen area
+application in compatibility mode, rendering it in a baseline screen area
(normal size, medium density) reserved on the larger screen. See
<a href="#compatibility-examples">Screen-Compatibility Examples</a> for an
illustration of what an application looks like when displayed in compatibility
@@ -803,7 +810,7 @@
<p>In some cases, you will need to express dimensions in <code>dip</code> and
then convert them to pixels. Imagine an application in which a scroll gesture is
recognized after the user's finger has moved by at least 16 pixels. On a
-baseline HVGA screen, the user will have to move his finger by 16 pixels / 160
+baseline screen, the user will have to move his finger by 16 pixels / 160
dpi = 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a
device with a high (240) density display, the user will move his finger by only
16 pixels / 240 dpi = 1/15th of an inch (or 1.7 mm.) The distance is much
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 3f00b5c..51ccfaf 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -681,7 +681,7 @@
<table style="margin:0px;padding:0px;">
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for outer glow and bevel highlight.</td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for outer glow and bevel highlight.</td>
</tr>
<tr>
@@ -691,7 +691,7 @@
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for inner shadow and bevel shadow.</td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for inner shadow and bevel shadow.</td>
</tr>
</table>
@@ -809,22 +809,22 @@
<table style="margin:0px;padding:0px;">
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for details within the icons and bevel highlight.</td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for details within the icons and bevel highlight.</td>
</tr>
<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
<td class="image-caption-c" style="padding-top:.5em;">Grey gradient<br><em>1: </em>r 169 | g 169 | b 169<br><em>2: </em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
</tr>
<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1: </em>1 r 105 | g 105 | b 105<br><em>2: </em>r 10 | g 10 | b 10<br>Used as color fill.</td>
</tr>
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for bevel shadow.</td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for bevel shadow.</td>
</tr>
</table>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
index 039f301..1c75843 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
@@ -169,7 +169,7 @@
<table style="margin:0px;padding:0px;">
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for highlights on edges.</td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for highlights on edges.</td>
</tr>
<tr>
@@ -189,7 +189,7 @@
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used as base color in shadows.</td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used as base color in shadows.</td>
</tr>
</table>
@@ -300,7 +300,7 @@
<table style="margin:0px;padding:0px;">
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for outer glow and bevel highlight.</td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for outer glow and bevel highlight.</td>
</tr>
<tr>
@@ -310,7 +310,7 @@
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for inner shadow and bevel shadow.</td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for inner shadow and bevel shadow.</td>
</tr>
</table>
@@ -412,22 +412,22 @@
<table style="margin:0px;padding:0px;">
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for details within the icons and bevel highlight.</td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 255 | g 255 | b 255<br>Used for details within the icons and bevel highlight.</td>
</tr>
<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
<td class="image-caption-c" style="padding-top:.5em;">Grey gradient<br><em>1: </em>r 169 | g 169 | b 169<br><em>2: </em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
</tr>
<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1: </em>1 r 105 | g 105 | b 105<br><em>2: </em>r 10 | g 10 | b 10<br>Used as color fill.</td>
</tr>
<tr>
<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for bevel shadow.</td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 0 | g 0 | b 0<br>Used for bevel shadow.</td>
</tr>
</table>
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 52f1353..293a057 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -145,7 +145,7 @@
<a name="files"></a>
-<h2 id="#filesInternal">Using the Internal Storage</h2>
+<h2 id="filesInternal">Using the Internal Storage</h2>
<p>You can save files directly on the device's internal storage. By default, files saved
to the internal storage are private to your application and other applications cannot access
@@ -225,7 +225,7 @@
-<h2 id="#filesExternal">Using the External Storage</h2>
+<h2 id="filesExternal">Using the External Storage</h2>
<p>Every Android-compatible device supports a shared "external storage" that you can use to
save files. This can be a removable storage media (such as an SD card) or an internal
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index 08f35e9..786223f 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -3,8 +3,7 @@
<dl class="xml">
<dt>syntax:</dt>
-<dd><pre class="stx"><application android:<a href="#backup">allowBackup</a>=["true" | "false"]
- android:<a href="#clear">allowClearUserData</a>=["true" | "false"]
+<dd><pre class="stx"><application android:<a href="#clear">allowClearUserData</a>=["true" | "false"]
android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
android:<a href="#agent">backupAgent</a>="<i>string</i>"
android:<a href="#debug">debuggable</a>=["true" | "false"]
@@ -49,15 +48,6 @@
<dt>attributes</dt>
<dd><dl class="attr">
-<dt><a name="backup"></a>{@code android:allowBackup}</dt>
-<dd>Whether the application allows its data to be backed up through the Android
-Backup Manager — "{@code true}" if it does, "{@code false}" if not. By
-default this attribute is "{@code true}". If an application declares this
-attribute to be "{@code false}" the Backup Manager will never attempt to
-perform any backup or restore operation, even if the application declares a
-valid <a href="#agent">{@code android:backupAgent}</a> attribute in its
-manifest.
-</dd>
<dt><a name="clear"></a>{@code android:allowClearUserData}</dt>
<dd>Whether or not users are given the option to remove user data —
diff --git a/docs/html/guide/topics/manifest/instrumentation-element.jd b/docs/html/guide/topics/manifest/instrumentation-element.jd
index 1fd1dd0..b18e777 100644
--- a/docs/html/guide/topics/manifest/instrumentation-element.jd
+++ b/docs/html/guide/topics/manifest/instrumentation-element.jd
@@ -51,10 +51,6 @@
There is no default. The name must be specified.
</p></dd>
-<!-- ##api level indication## -->
-<dt>introduced in:</dt>
-<dd>API Level 1</dd>
-
<dt><a name="trgt"></a>{@code android:targetPackage}</dt>
<dd>The application that the Instrumentation object will run against.
An application is identified by the package name assigned in its manifest
@@ -62,4 +58,8 @@
</dl></dd>
+<!-- ##api level indication## -->
+<dt>introduced in:</dt>
+<dd>API Level 1</dd>
+
</dl>
diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd
index 3353755..a35c5a1 100644
--- a/docs/html/guide/topics/manifest/manifest-element.jd
+++ b/docs/html/guide/topics/manifest/manifest-element.jd
@@ -161,6 +161,7 @@
<p>Introduced in: API Level 8.</p>
+
</dd>
</dl>
diff --git a/docs/html/guide/topics/manifest/path-permission-element.jd b/docs/html/guide/topics/manifest/path-permission-element.jd
new file mode 100644
index 0000000..5c271a7
--- /dev/null
+++ b/docs/html/guide/topics/manifest/path-permission-element.jd
@@ -0,0 +1,104 @@
+page.title=<path-permission>
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">
+<path-permission android:<a href="#path">path</a>="<i>string</i>"
+ android:<a href="#pathPrefix">pathPrefix</a>="<i>string</i>"
+ android:<a href="#pathPattern">pathPattern</a>="<i>string</i>"
+ android:<a href="#permission">permission</a>="<i>string</i>"
+ android:<a href="#readPermission">readPermission</a>="<i>string</i>"
+ android:<a href="#writePermission">writePermission</a>="<i>string</i>" />
+</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code></dd>
+
+<!--
+<dt>can contain:</dt>
+</dd>
+-->
+
+<dt>description:</dt>
+<dd>Defines the path and required permissions for a specific subset of data
+within a content provider. This element can be
+specified multiple times to supply multiple paths.
+
+</dd>
+
+<dt>attributes:</dt>
+
+<dd><dl class="attr">
+<dt><a name="path"></a>{@code android:path}</dt>
+<dd>A complete URI path for a subset of content provider data.
+Permission can be granted only to the particular data identified by this path.
+When used to provide search suggestion content, it must be appended
+with "/search_suggest_query".
+</dd>
+
+<dt><a name="pathPrefix"></a>{@code android:pathPrefix}</dt>
+<dd>The initial part of a URI path for a subset of content provider data.
+Permission can be granted to all data subsets with paths that share this initial part.
+</dd>
+
+<dt><a name="pathPattern"></a>{@code android:pathPattern}</dt>
+<dd>A complete URI path for a subset of content provider data,
+but one that can use the following wildcards:
+
+<ul>
+<li>An asterisk ('<code class="Code prettyprint">*</code>'). This matches a sequence of 0 to many occurrences of
+the immediately preceding character.</li>
+
+<li>A period followed by an asterisk ("<code class="Code prettyprint">.*</code>"). This matches any sequence of
+0 or more characters.</li>
+</ul>
+
+<p>
+Because '<code class="Code prettyprint">\</code>' is used as an escape character when the string is read
+from XML (before it is parsed as a pattern), you will need to double-escape.
+For example, a literal '<code class="Code prettyprint">*</code>' would be written as "<code class="Code prettyprint">\\*</code>" and a
+literal '<code class="Code prettyprint">\</code>' would be written as "<code class="Code prettyprint">\\</code>". This is basically
+the same as what you would need to write if constructing the string in Java code.
+</p>
+<p>
+For more information on these types of patterns, see the descriptions of
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_LITERAL">PATTERN_LITERAL</a>,
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_PREFIX">PATTERN_PREFIX</a>, and
+<a href="/reference/android/os/PatternMatcher.html#PATTERN_SIMPLE_GLOB">PATTERN_SIMPLE_GLOB</a> in the
+<a href="/reference/android/os/PatternMatcher.html">PatternMatcher</a> class.
+</p>
+</dd>
+
+<dt><a name="permission"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have in order to read or write the
+content provider's data. This attribute is a convenient way of setting a
+single permission for both reading and writing. However, the
+<code>readPermission</code> and
+<code>writePermission</code> attributes take precedence
+over this one.
+</dd>
+
+<dt><a name="readPermission"></a>{@code android:readPermission}</dt>
+<dd>A permission that clients must have in order to query the content provider.
+</dd>
+
+<dt><a name="writePermission"></a>{@code android:writePermission}</dt>
+<dd>A permission that clients must have in order to make changes to the data controlled by the content provider.
+</dd>
+
+
+
+</dl></dd>
+
+<!-- ##api level indication## -->
+<dt>introduced in:</dt>
+<dd>API Level 4</dd>
+
+<dt>see also:</dt>
+<dd>{@link android.app.SearchManager}</dd>
+<dd>{@link android.Manifest.permission}</dd>
+<dd><a href="/guide/topics/security/security.html">Security and
+Permissions</a></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/resources/accessing-resources.jd b/docs/html/guide/topics/resources/accessing-resources.jd
index cf8970c..03bb939 100644
--- a/docs/html/guide/topics/resources/accessing-resources.jd
+++ b/docs/html/guide/topics/resources/accessing-resources.jd
@@ -136,7 +136,7 @@
without the extension or the {@code android:name} attribute value in the XML element (for simple
values).</li>
</ul>
-<p>See <a href="resource-types.html">Resource Types</a> for
+<p>See <a href="available-resources.html">Resource Types</a> for
more information about each resource type and how to reference them.</p>
@@ -219,7 +219,7 @@
values).</li>
</ul>
-<p>See <a href="resource-types.html">Resource Types</a> for
+<p>See <a href="available-resources.html">Resource Types</a> for
more information about each resource type and how to reference them.</p>
diff --git a/docs/html/guide/topics/resources/layout-resource.jd b/docs/html/guide/topics/resources/layout-resource.jd
index 2c51d54..0688a18 100644
--- a/docs/html/guide/topics/resources/layout-resource.jd
+++ b/docs/html/guide/topics/resources/layout-resource.jd
@@ -97,7 +97,8 @@
{@link android.view.ViewGroup}. For a reference of all available attributes,
see the corresponding reference documentation for the {@link android.view.ViewGroup} class
(for example, the <a
- href="{@docRoot}reference/android/widget/LinearLayout#lattrs">LinearLayout XML attributes</a>).</p>
+ href="{@docRoot}reference/android/widget/LinearLayout.html#lattrs">LinearLayout XML
+attributes</a>).</p>
</dd>
<dt id="view-element"><code><View></code></dt>
<dd>An individual UI component, generally referred to as a "widget". Different
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index e76a92c..3d630c9d 100755
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -317,11 +317,11 @@
<p>The selection process is not always as straightforward as these examples
suggest. Please read <a
-href="{@docRoot}guide/topics/resources/creating-resources.html#BestMatch">How Android Finds
+href="{@docRoot}guide/topics/resources/providing-resources.html#BestMatch">How Android Finds
the Best-matching Resource</a> for a more nuanced description of the
process. All the qualifiers are described and listed in order of
precedence in <a
-href="{@docRoot}guide/topics/resources/creating-resources.html#table2">Table 2 of Providing
+href="{@docRoot}guide/topics/resources/providing-resources.html#table2">Table 2 of Providing
Alternative Resources</a>.</p>
<h3 id="referring-to-resources">Referring to Resources in Java</h3>
@@ -330,7 +330,7 @@
<code>R.<em>resource_type</em>.<em>resource_name</em></code> or
<code>android.R.<em>resource_type</em>.<em>resource_name</em></code><em>.</em>
For more about this, see <a
-href="{@docRoot}guide/topics/resources/using-resources.html">Accessing Resources</a>.</p>
+href="{@docRoot}guide/topics/resources/accessing-resources.html">Accessing Resources</a>.</p>
<h2 id="strategies">Localization Strategies</h2>
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index 718668c..a5f99c7 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -275,8 +275,8 @@
<li>If your data is stored online, then the perceived search performance may be
inhibited by the user's data connection. You may want to display a spinning progress wheel until
your search returns. See {@link android.net} for a reference of network APIs and <a
-href="guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a> to see how
-you can display a progress wheel.</li>
+href="{@docRoot}guide/topics/ui/dialogs.html#ProgressDialog">Creating a Progress Dialog</a> to see
+how you can display a progress wheel.</li>
</ul>
diff --git a/docs/html/guide/topics/testing/testing_android.jd b/docs/html/guide/topics/testing/testing_android.jd
index 531aea1..46ba769 100755
--- a/docs/html/guide/topics/testing/testing_android.jd
+++ b/docs/html/guide/topics/testing/testing_android.jd
@@ -1,5 +1,6 @@
page.title=Testing and Instrumentation
@jd:body
+
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
@@ -80,61 +81,84 @@
</ol>
</div>
</div>
-<p>
-Android includes a powerful set of testing tools that extend the industry-standard JUnit test framework with features specific to the Android environment. Although you can
-test an Android application with JUnit, the Android tools allow you to write much more sophisticated tests for every aspect of your application, both at the unit and at the framework level.
-</p>
-<p>
-Key features of the Android testing environment include:
-</p>
+
+<p>Android includes a powerful set of testing tools that extend the
+industry-standard JUnit test framework with features specific to the Android
+environment. Although you can test an Android application with JUnit, the
+Android tools allow you to write much more sophisticated tests for every aspect
+of your application, both at the unit and framework levels.</p>
+
+<p>Key features of the Android testing environment include:</p>
+
<ul>
- <li>Android extensions to the JUnit framework that provide access to Android system objects.</li>
- <li>An instrumentation framework that lets tests control and examine the application.</li>
+ <li>Android extensions to the JUnit framework that provide access to Android
+system objects.</li>
+ <li>An instrumentation framework that lets tests control and examine the
+application.</li>
<li>Mock versions of commonly-used Android system objects.</li>
- <li>Tools for running single tests or test suites, with or without instrumentation.</li>
- <li>Support for managing tests and test projects in the ADT Plugin for Eclipse and at the command line.</li>
+ <li>Tools for running single tests or test suites, with or without
+instrumentation.</li>
+ <li>Support for managing tests and test projects in the ADT Plugin for Eclipse
+and at the command line.</li>
</ul>
-<p>
-This document is an overview of the Android testing environment and the way you use it. The document assumes you have a basic knowledge of
-Android application programming and JUnit testing methodology.
-</p>
+
+<p>This document is an overview of the Android testing environment and the way
+you use it. The document assumes you have a basic knowledge of Android
+application programming and JUnit testing methodology.</p>
+
<h2 id="Overview">Overview</h2>
-<p>
-At the heart of the Android testing environment is an instrumentation framework that your test application uses to precisely control the application under test. With instrumentation, you can
-set up mock system objects such as Contexts before the main application starts, control your application at various points of its lifecycle, send UI events to the application, and
-examine the application's state during its execution. The instrumentation framework accomplishes this by running both the main application and the test application in the same process.
-</p>
-<p>
- Your test application's manifest file links it to the application under test. The the <instrumentation> attribute in the manifest file points to the application under test
- and also tells Android how to run the test application. This is described in more detail in the section <a href="#InstrumentationTestRunner">Instrumentation Test Runner</a>.
-</p>
-<p>
-The following diagram summarizes the Android testing environment:
-</p>
+
+<p> At the heart of the Android testing environment is an instrumentation
+framework that your test application uses to precisely control the application
+under test. With instrumentation, you can set up mock system objects such as
+Contexts before the main application starts, control your application at various
+points of its lifecycle, send UI events to the application, and examine the
+application's state during its execution. The instrumentation framework
+accomplishes this by running both the main application and the test application
+in the same process. </p>
+
+<p>Your test application is linked to the application under test by means of an
+<a
+href="{@docRoot}guide/topics/manifest/instrumentation-element.html"><code><instrumentation></code></a>
+element in the test application's manifest file. The attributes of the element
+specify the package name of the application under test and also tell Android how
+to run the test application. Instrumentation is described in more detail in the
+section <a href="#InstrumentationTestRunner">Instrumentation Test
+Runner</a>.</p>
+
+<p>The following diagram summarizes the Android testing environment:</p>
+
<img src="{@docRoot}images/testing/android_test_framework.png"/>
-<p>
- In Android, test applications are themselves Android applications, so you write them in much the same way as the application you are testing. The SDK tools
- help you create a main application project and its test project at the same time. You can run Android tests within Eclipse with ADT or from the command line.
- Eclipse with ADT provides an extensive set of tools for creating tests, running them, and viewing their results. You can also use the <code>adb</code> tool to
- run tests, or use a built-in Ant target.
-</p>
-<p>
- To learn how to set up and run tests in Eclipse, please refer to <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in Eclipse, with ADT</a>.
- If you're not working in Eclipse, refer to <a href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other IDEs</a>.
-</p>
-<p>
- If you want a step-by-step introduction to Android testing, try one of the testing tutorials:
-</p>
- <ul>
- <li>
- The <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello, Testing</a> tutorial introduces basic testing concepts and procedures in the
- context of the Hello, World application.
- </li>
- <li>
- The <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
- It guides you through a more complex testing scenario that you develop against a more realistic application.
- </li>
- </ul>
+
+<p>In Android, test applications are themselves Android applications, so you
+write them in much the same way as the application you are testing. The SDK
+tools help you create a main application project and its test project at the same
+time. You can run Android tests within Eclipse with ADT or from the command
+line. Eclipse with ADT provides an extensive set of tools for creating tests,
+running them, and viewing their results. You can also use the <code>adb</code>
+tool to run tests, or use a built-in Ant target.</p>
+
+<p>To learn how to set up and run tests in Eclipse, please refer to <a
+href="{@docRoot}guide/developing/testing/testing_eclipse.html">Testing in
+Eclipse, with ADT</a>. If you're not working in Eclipse, refer to <a
+href="{@docRoot}guide/developing/testing/testing_otheride.html">Testing in Other
+IDEs</a>.</p>
+
+<p>If you want a step-by-step introduction to Android testing, try one of the
+testing tutorials:</p>
+
+<ul>
+ <li>The <a
+href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">Hello,
+Testing</a> tutorial introduces basic testing concepts and procedures in the
+context of the Hello, World application.</li>
+ <li>The <a
+href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity
+Testing</a> tutorial is an excellent follow-up to the Hello, Testing tutorial.
+It guides you through a more complex testing scenario that you develop against a
+more realistic application.</li>
+</ul>
+
<h2 id="TestAPI">The Testing API</h2>
<p>
For writing tests and test applications in the Java programming language, Android provides a
diff --git a/docs/html/images/home/io-logo.png b/docs/html/images/home/io-logo.png
new file mode 100644
index 0000000..f579ca2
--- /dev/null
+++ b/docs/html/images/home/io-logo.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index dd42ced..230dd4e 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -11,10 +11,13 @@
</div><!-- end homeTitle -->
<div id="announcement-block">
<!-- total max width is 520px -->
- <img src="{@docRoot}assets/images/home/gdc-logo.png" alt="Android at GDC 2010" width="203px" style="padding-left:22px;padding-bottom:28px;padding-top:22px;"/>
- <div id="announcement" style="width:275px">
-<p>Thanks to everyone who attended our sessions at the <a href="http://www.gdconf.com/">2010 Game Developers Conference</a> in San Francisco. We're looking forward to seeing your games running on Android!</p>
-<p><a href="http://android-developers.blogspot.com/2010/03/android-at-game-developers-conference.html">Learn more »</a></p>
+ <img src="{@docRoot}images/home/io-logo.png" alt="Google IO
+2010" width="200" height="41" style="padding:22px 12px;"/>
+ <div id="announcement" style="width:295px">
+<p>Google I/O is happening now! To those of you with us, welcome! If you couldn't make it to the
+event, stay tuned for videos and slides from the Android sessions, which will be posted at the
+Google I/O web site.</p><p><a
+href="http://code.google.com/events/io/2010/sessions.html#Android">Learn more »</a></p>
</div> <!-- end annoucement -->
</div> <!-- end annoucement-block -->
</div><!-- end topAnnouncement -->
@@ -125,17 +128,17 @@
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"Android 2.1",
- 'img':"sdk-large.png",
- 'title':"Android 2.1 is now available",
- 'desc': "<p>Android 2.1 is a small feature release that includes new developer APIs "
- + "and documentation. For information about what's included in the platform, "
- + "read the <a href='{@docRoot}sdk/android-2.1.html'>Android 2.1 "
- + "version notes</a>.</p>"
- + "<p>You can update your existing development environment "
- + "by installing the Android 2.1 platform as an "
- + "<a href='{@docRoot}sdk/adding-components.html'>SDK "
- + "component</a>."
+ 'name':"Android 2.2",
+ 'img':"froyo-android.png",
+ 'title':"Get Android 2.2!",
+ 'desc': "<p>The Android 2.2 platform is now available for the Android SDK, along with new "
++ "tools, documentation, and a new NDK. "
++ "For information about new features and APIs, read the "
++ "<a href='{@docRoot}sdk/android-2.2.html'>version notes</a>.</p>"
++ "<p>If you have an existing SDK, add Android 2.2 as an "
++ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
++ "component</a>. If you're new to Android, install the "
++ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
},
'adc2': {
@@ -174,15 +177,6 @@
'img':"maps-large.png",
'title':"Maps API Key",
'desc':"<p>If you're writing an Android application that uses Google Maps (with MapView), you must register your application to obtain a Maps API Key. Without the key, your maps application will not work on Android devices. Obtaining a key requires just a couple of steps.</p><p><a href='http://code.google.com/android/add-ons/google-apis/maps-overview.html'>Learn more »</a></p>"
- },
-
- 'io': {
- 'layout':"imgLeft",
- 'icon':"io-small.png",
- 'name':"Google I/O",
- 'img':"io-large.png",
- 'title':"Google I/O Developer Conference",
- 'desc': "<p>The Google I/O developer conference took place May 27-28 in San Francisco. If you missed the conference, you can experience the Android sessions by viewing YouTube videos.</p><p><a href='{@docRoot}videos/index.html'>See the sessions from Google I/O »</a></p>"
}
}
diff --git a/docs/html/resources/articles/backward-compatibility.jd b/docs/html/resources/articles/backward-compatibility.jd
index e7f0b60..4b1a34c 100644
--- a/docs/html/resources/articles/backward-compatibility.jd
+++ b/docs/html/resources/articles/backward-compatibility.jd
@@ -1,6 +1,18 @@
page.title=Backward Compatibility for Applications
@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a></li>
+ </ol>
+
+</div>
+</div>
+
<p>A variety of Android-powered devices are now available to consumers from carriers
in geographies around the world. Across those devices, a range of Android
platform versions are in use, some running the latest version of the platform,
diff --git a/docs/html/resources/articles/creating-input-method.jd b/docs/html/resources/articles/creating-input-method.jd
index 5a92970..6f932df 100644
--- a/docs/html/resources/articles/creating-input-method.jd
+++ b/docs/html/resources/articles/creating-input-method.jd
@@ -2,6 +2,19 @@
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/articles/on-screen-inputs.html">Onscreen Input Methods</a></li>
+ <li><a href="{@docRoot}resources/samples/SoftKeyboard/index.html">Soft Keyboard sample</a></li>
+ </ol>
+
+</div>
+</div>
+
+
<p>To create an input method (IME) for entering text into text fields
and other Views, you need to extend the {@link android.inputmethodservice.InputMethodService}.
class. This class provides much of the basic implementation for an input
diff --git a/docs/html/resources/articles/faster-screen-orientation-change.jd b/docs/html/resources/articles/faster-screen-orientation-change.jd
index c500035..f82e592 100644
--- a/docs/html/resources/articles/faster-screen-orientation-change.jd
+++ b/docs/html/resources/articles/faster-screen-orientation-change.jd
@@ -1,6 +1,19 @@
page.title=Faster Screen Orientation Change
@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling Runtime
+Changes</a></li>
+ </ol>
+
+</div>
+</div>
+
<p>Android is designed to run efficiently on a wide
array of devices, with very different hardware configurations. Some
devices, like the T-Mobile G1, can change their hardware configuration
diff --git a/docs/html/resources/articles/live-wallpapers.jd b/docs/html/resources/articles/live-wallpapers.jd
index 8dda879..ea67fed 100644
--- a/docs/html/resources/articles/live-wallpapers.jd
+++ b/docs/html/resources/articles/live-wallpapers.jd
@@ -1,6 +1,19 @@
page.title=Live Wallpapers
@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/samples/CubeLiveWallpaper/index.html">Live Wallpaper
+sample</a></li>
+ </ol>
+
+</div>
+</div>
+
<p>Starting with Android 2.1 (API Level 7), users can now enjoy <em>live
wallpapers</em> — richer, animated, interactive backgrounds — on
their home screens. A live wallpaper is very similar to a normal Android
@@ -23,8 +36,8 @@
<p>In terms of implementation, a live wallpaper is very similar to a regular
Android <a href="../../../reference/android/app/Service.html">service</a>. The
only difference is the addition of a new method, <a
-href="../../../reference/android/service/wallpaper/WallpaperService.
-html#onCreateEngine()"><code>onCreateEngine()</code></a>, whose goal is to create a <a
+href="../../../reference/android/service/wallpaper/WallpaperService.html#onCreateEngine()">{@code
+onCreateEngine()}</a>, whose goal is to create a <a
href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html">
<code>WallpaperService.Engine</code></a>. The engine is responsible for
handling the lifecycle and drawing of a wallpaper. The system provides a surface
diff --git a/docs/html/resources/articles/on-screen-inputs.jd b/docs/html/resources/articles/on-screen-inputs.jd
index 057325a..30b4c84 100644
--- a/docs/html/resources/articles/on-screen-inputs.jd
+++ b/docs/html/resources/articles/on-screen-inputs.jd
@@ -2,6 +2,20 @@
@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/articles/creating-input-method.html">Creating an Input
+Method</a></li>
+ <li><a href="{@docRoot}resources/samples/SoftKeyboard/index.html">Soft Keyboard sample</a></li>
+ </ol>
+
+</div>
+</div>
+
+
<p>Starting from Android 1.5, the Android platform offers an Input Method
Framework (IMF) that lets you create on-screen input methods such as software
keyboards. This article provide an overview of what Android input method editors
diff --git a/docs/html/resources/articles/qsb.jd b/docs/html/resources/articles/qsb.jd
index e497f50..d47ba54 100644
--- a/docs/html/resources/articles/qsb.jd
+++ b/docs/html/resources/articles/qsb.jd
@@ -1,7 +1,23 @@
page.title=Quick Search Box
@jd:body
-<img src="images/qsb_002.png" style="float: right; margin-left: 2em; margin-bottom: 1em; width: 233px; height: 349.5px;"></p>
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/search/index.html">Search</a></li>
+ <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable Dictionary
+sample</a></li>
+ </ol>
+
+</div>
+</div>
+
+<div class="figure" style="width:233px">
+<img src="images/qsb_002.png" alt="" height="350" />
+</div>
<p>Starting with Android 1.6, the platform includes support for Quick Search
Box (QSB), a powerful, system-wide search framework. Quick Search Box makes it
diff --git a/docs/html/resources/articles/speech-input.jd b/docs/html/resources/articles/speech-input.jd
index 8e41d34..282b619 100644
--- a/docs/html/resources/articles/speech-input.jd
+++ b/docs/html/resources/articles/speech-input.jd
@@ -29,9 +29,8 @@
<p> The Android SDK makes it easy to integrate speech input directly into your
own application. Just copy and paste from this <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/
-VoiceRecognition.html">
-sample application</a> to get
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/VoiceRecognition.html">sample
+application</a> to get
started. The sample application first verifies that the target device is able
to recognize speech input:</p>
<pre>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index f5a82f8..0d6ecc4 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -18,7 +18,8 @@
</a></li>
</ul>
</li>
-
+<?cs
+ if:android.whichdoc == "online" ?>
<li>
<h2><span class="en">Device Dashboard</span>
</h2>
@@ -27,7 +28,9 @@
<span class="en">Platform Versions</span>
</a></li>
</ul>
- </li>
+ </li><?cs
+ /if
+?>
<li>
<h2><span class="en">Technical Articles</span>
diff --git a/docs/html/resources/samples/get.jd b/docs/html/resources/samples/get.jd
index 898bc49..1b6d137 100644
--- a/docs/html/resources/samples/get.jd
+++ b/docs/html/resources/samples/get.jd
@@ -40,7 +40,7 @@
computer in this location:</p>
<p style="margin-left:2em">
-<code><em><sdk></em>/samples/<em><platform-version></em>/</code>
+<code><em><sdk></em>/samples/android-<<em>level</em>>/</code>
</p>
<p>You can easily create new Android projects with the downloaded samples, modify them
@@ -49,7 +49,7 @@
<p>For example, if you are developing in Eclipse with the ADT Plugin, you can
create a project for the "API Demos" sample app by starting a new Android
Project, selecting "Create project from existing source", and then browsing to
-the <code><em><sdk></em>/samples/<em><platform></em>/ApiDemos</code>
+the <code><em><sdk></em>/samples/android-<<em>level</em>>/ApiDemos</code>
directory (the <code>samples</code> directory for the platform version you are
using).</p>
@@ -57,7 +57,7 @@
sample using the <code>android</code> tool, by executing this command:</p>
<pre class="no-pretty-print">
-android update project -s -n API Demos -t <em><target_ID></em> -p <em><path></em>samples/<em><platforms></em>/ApiDemos/
+android update project -s -n API Demos -t <em><target_ID></em> -p <<em>path</em>></em>samples/android-<<em>level</em>>/ApiDemos/
</pre>
<h3 id="browsing">Browsing the Sample Code</h3>
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 4019200..9fc8e0bf 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -23,7 +23,7 @@
framework topics.</dd>
<dt><a href="BackupRestore/index.html">Backup and Restore</a></dt>
- <dd>An simple example that illustrates a few different ways for an application to
+ <dd>A simple example that illustrates a few different ways for an application to
implement support for the Android data backup and restore mechanism.</dd>
<dt><a href="BluetoothChat/index.html">Bluetooth Chat</a></dt>
diff --git a/docs/html/resources/tutorials/hello-world.jd b/docs/html/resources/tutorials/hello-world.jd
index 1079fb5..7bad054 100644
--- a/docs/html/resources/tutorials/hello-world.jd
+++ b/docs/html/resources/tutorials/hello-world.jd
@@ -260,14 +260,16 @@
<div class="sidebox-wrapper">
<div class="sidebox">
<p>To learn more about creating and editing run configurations in Eclipse, refer to
- <a href="{@docRoot}guide/developing/eclipse-adt.html#RunConfig">Developing In Eclipse,
+ <a href="{@docRoot}guide/developing/eclipse-adt.html#RunConfig">Developing In Eclipse,
with ADT</a>.</p>
</div>
</div>
-<p>The Eclipse ADT will automatically create a new run configuration for your project
-and the Android Emulator will automatically launch. Once the emulator is booted up,
-your application will appear after a moment. You should now see something like this:</p>
+<p>The Eclipse plugin automatically creates a new run configuration for your project
+and then launches the Android Emulator. Depending on your environment, the Android
+emulator might take several minutes to boot fully, so please be patient. When the
+emulator is booted, the Eclipse plugin installs your application
+and launches the default Activity. You should now see something like this:</p>
<a href="images/hello_world_5.png"><img src="images/hello_world_5.png" style="height:230px" alt="" /></a>
diff --git a/docs/html/resources/tutorials/testing/activity_test.jd b/docs/html/resources/tutorials/testing/activity_test.jd
index ae4b6f3..87dd183 100644
--- a/docs/html/resources/tutorials/testing/activity_test.jd
+++ b/docs/html/resources/tutorials/testing/activity_test.jd
@@ -1208,8 +1208,8 @@
Close Eclipse with ADT.
</li>
<li>
- Copy the file <code><SDK_path>/samples/android-8/SpinnerTest/src/com/android/examples/spinner/test/SpinnerActivityTest.java</code>
- to the directory <code>workspace/SpinnerActivityTest/src/com/android/examples/spinner/test/</code>.
+ Copy the file <code><SDK_path>/samples/android-8/SpinnerTest/src/com/android/example/spinner/test/SpinnerActivityTest.java</code>
+ to the directory <code>workspace/SpinnerActivityTest/src/com/android/example/spinner/test/</code>.
</li>
<li>
Restart Eclipse with ADT.
diff --git a/docs/html/sdk/adding-components.jd b/docs/html/sdk/adding-components.jd
index 90e9045..63c577e 100644
--- a/docs/html/sdk/adding-components.jd
+++ b/docs/html/sdk/adding-components.jd
@@ -127,10 +127,12 @@
</ol>
<p>New platforms are automatically saved into the
-<code><em><sdk>/</em>platforms/</code> directory of your SDK;
-new add-ons are saved in the <code><em><sdk>/</em>add-ons/</code>
-directory; and new documentation is saved in the existing
-<code><em><sdk>/</em>docs/</code> directory (old docs are replaced).</p>
+<code><<em>sdk</em>>/platforms/</code> directory of your SDK;
+new add-ons are saved in the <code><<em>sdk</em>>/add-ons/</code>
+directory; samples are saved in the
+<code><<em>sdk</em>>/samples/android-<<em>level</em>>/</code>;
+and new documentation is saved in the existing
+<code><<em>sdk</em>>/docs/</code> directory (old docs are replaced).</p>
<h2 id="UpdatingComponents">Updating SDK Components</h2>
diff --git a/docs/html/sdk/android-1.5.jd b/docs/html/sdk/android-1.5.jd
index b3eea77..ab74631 100644
--- a/docs/html/sdk/android-1.5.jd
+++ b/docs/html/sdk/android-1.5.jd
@@ -96,6 +96,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -107,6 +110,29 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ Android 1.5, Revision 4</a> <em>(May 2010)</em></a>
+ <div class="toggleme">
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires SDK Tools r6 or higher.</p>
+</dd>
+
+<dt>Tools:</dt>
+<dd>
+<ul>
+<li>Adds support for library projects in the Ant build system.</li>
+<li>Fixes test project build in the Ant build system.</li>
+</ul>
+</dd>
+
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
Android 1.5, Revision 3</a> <em>(July 2009)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd
index e0bac41..d7d14e9 100644
--- a/docs/html/sdk/android-1.6.jd
+++ b/docs/html/sdk/android-1.6.jd
@@ -98,6 +98,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -109,6 +112,26 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ Android 1.6, Revision 3</a> <em>(May 2010)</em></a>
+ <div class="toggleme">
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires SDK Tools r6 or higher.</p>
+</dd>
+<dt>Tools:</dt>
+<dd>
+<ul>
+<li>Adds support for library projects in the Ant build system.</li>
+</ul>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
Android 1.6, Revision 2</a> <em>(December 2009)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-2.1.jd b/docs/html/sdk/android-2.1.jd
index dfa82b3..db9c491 100644
--- a/docs/html/sdk/android-2.1.jd
+++ b/docs/html/sdk/android-2.1.jd
@@ -99,6 +99,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -110,6 +113,29 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ Android 2.1, Revision 2</a> <em>(May 2010)</em></a>
+ <div class="toggleme">
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires SDK Tools r6 or higher.</p>
+</dd>
+
+<dt>Tools:</dt>
+<dd>
+<ul>
+<li>Adds support for library projects in the Ant build system.</li>
+<li>Adds improved layout rendering in ADT’s visual layout editor.</li>
+</ul>
+</dd>
+
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
Android 2.1, Revision 1</a> <em>(January 2010)</em></a>
<div class="toggleme">
<dl>
diff --git a/docs/html/sdk/android-2.2.jd b/docs/html/sdk/android-2.2.jd
new file mode 100644
index 0000000..5844256
--- /dev/null
+++ b/docs/html/sdk/android-2.2.jd
@@ -0,0 +1,472 @@
+page.title=Android 2.2 Platform
+sdk.platform.version=2.2
+sdk.platform.apiLevel=8
+sdk.platform.majorMinor=minor
+sdk.platform.deployableDate=May 2010
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#features">Platform Highlights</a></li>
+ <li><a href="#relnotes">Revisions</a></li>
+ <li><a href="#apps">Built-in Applications</a></li>
+ <li><a href="#locs">Locales</a></li>
+ <li><a href="#skins">Emulator Skins</a></li>
+ <li><a href="#api">Framework API</a>
+ <ol>
+ <li><a href="#api-level">API level</a></li>
+ <li><a href="#api-changes">API changes summary</a></li>
+ <li><a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
+differences report »</a> </li>
+ </ol>
+ </li>
+</ol>
+
+<h2>See Also</h2>
+<ol>
+ <li><a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>
+<em>API Level:</em> <strong>{@sdkPlatformApiLevel}</strong></p>
+
+<p>Android {@sdkPlatformVersion} is a {@sdkPlatformMajorMinor} platform release
+deployable to Android-powered handsets starting in {@sdkPlatformDeployableDate}.
+This release includes user features, developer features, API changes, and bug
+fixes. For information on developer features and API changes, see the
+<a href="#api">Framework API</a> section.</p>
+
+<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
+downloadable component for the Android SDK. The downloadable platform includes a
+fully compliant Android library and system image, as well as a set of emulator
+skins, sample applications, and more. The downloadable platform
+includes no external libraries. </p>
+
+<p>To get started developing or testing against the Android
+{@sdkPlatformVersion} platform, use the Android SDK and AVD Manager tool to
+download the platform into your SDK. For more information,
+see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>. If you are new to Android, <a
+href="{@docRoot}sdk/index.html">download the SDK Starter Package</a>
+first.</p>
+
+
+<h2 id="features">Platform Highlights</h2>
+
+<p>For a list of new user features and platform highlights, see the <a
+href="http://developer.android.com/sdk/android-2.2-highlights.html">Android
+2.2 Platform Highlights</a> document.</p>
+
+<h2 id="relnotes">Revisions</h2>
+
+<p>The sections below provide notes about successive releases of
+the Android {@sdkPlatformVersion} platform component for the Android SDK, as denoted by
+revision number. To determine what revision(s) of the Android
+{@sdkPlatformVersion} platforms are installed in your SDK environment, refer to
+the "Installed Packages" listing in the Android SDK and AVD Manager.</p>
+
+<script type="text/javascript">
+function toggleDiv(link) {
+ var toggleable = $(link).parent();
+ if (toggleable.hasClass("closed")) {
+ //$(".toggleme", toggleable).slideDown("fast");
+ toggleable.removeClass("closed");
+ toggleable.addClass("open");
+ $(".toggle-img", toggleable).attr("title", "hide").attr("src", (toRoot + "assets/images/triangle-opened.png"));
+ } else {
+ //$(".toggleme", toggleable).slideUp("fast");
+ toggleable.removeClass("open");
+ toggleable.addClass("closed");
+ $(".toggle-img", toggleable).attr("title", "show").attr("src", (toRoot + "assets/images/triangle-closed.png"));
+ }
+ return false;
+}
+</script>
+<style>
+.toggleable {
+padding: .25em 1em;
+}
+.toggleme {
+ padding: 1em 1em 0 2em;
+ line-height:1em;
+}
+.toggleable a {
+ text-decoration:none;
+}
+.toggleme a {
+ text-decoration:underline;
+}
+.toggleable.closed .toggleme {
+ display:none;
+}
+#jd-content .toggle-img {
+ margin:0;
+}
+</style>
+
+<div class="toggleable opened">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+ Android {@sdkPlatformVersion}, Revision 1</a> <em>(May 2010)</em></a>
+ <div class="toggleme">
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>Requires SDK Tools r6 or higher.</p>
+</dd>
+
+<dt>Tools:</dt>
+<dd>
+<ul>
+<li>Adds support for building with Android library projects, a capability that
+lets you store shared Android application code and resources in a separate
+development project. You can then reference the library project from other
+Android projects and, at build time, the tools compile the shared code and
+resources as part of the dependent applications. More information about this
+feature is available in the <a
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing in
+Eclipse, with ADT</a> and <a
+href="{@docRoot}guide/developing/other-ide.html#libraryProject">Developing in
+Other IDEs</a> documents. </li>
+</li>
+</ul>
+</dd>
+
+</dl>
+ </div>
+</div>
+
+<h2 id="apps">Built-in Applications</h2>
+
+<p>The system image included in the downloadable platform provides these
+built-in applications:</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+ <ul>
+ <li>Alarm Clock</li>
+ <li>Browser</li>
+ <li>Calculator</li>
+ <li>Camera</li>
+ <li>Contacts</li>
+ <li>Custom Locale (developer app)</li>
+ <li>Dev Tools (developer app)</li>
+ <li>Email</li>
+ </ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+ <ul>
+
+ <li>Gallery</li>
+ <li>IMEs for Japanese, Chinese, and Latin text input</li>
+ <li>Messaging</li>
+ <li>Music</li>
+ <li>Phone</li>
+ <li>Settings</li>
+ <li>Spare Parts (developer app)</li>
+ </ul>
+</td>
+</tr>
+</table>
+
+
+<h2 id="locs" style="margin-top:.75em;">Locales</h2>
+
+<p>The system image included in the downloadable platform provides a variety of
+built-in locales. In some cases, region-specific strings are available for the
+locales. In other cases, a default version of the language is used. The
+languages that are available in the Android {@sdkPlatformVersion} system
+image are listed below (with <em>language</em>_<em>country/region</em> locale
+descriptor).</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Chinese, PRC (zh_CN)</li>
+<li>Chinese, Taiwan (zh_TW)</li>
+<li>Czech (cs_CZ)</li>
+<li>Dutch, Netherlands (nl_NL)</li>
+<li>Dutch, Belgium (nl_BE)</li>
+<li>English, US (en_US)</li>
+<li>English, Britain (en_GB)</li>
+<li>English, Canada (en_CA)</li>
+<li>English, Australia (en_AU)</li>
+<li>English, New Zealand (en_NZ)</li>
+<li>English, Singapore(en_SG)</li>
+<li>French, France (fr_FR)</li>
+<li>French, Belgium (fr_BE)</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<li>French, Canada (fr_CA)</li>
+<li>French, Switzerland (fr_CH)</li>
+<li>German, Germany (de_DE)</li>
+<li>German, Austria (de_AT)</li>
+<li>German, Switzerland (de_CH)</li>
+<li>German, Liechtenstein (de_LI)</li>
+<li>Italian, Italy (it_IT)</li>
+<li>Italian, Switzerland (it_CH)</li>
+<li>Japanese (ja_JP)</li>
+<li>Korean (ko_KR)</li>
+<li>Polish (pl_PL)</li>
+<li>Russian (ru_RU)</li>
+<li>Spanish (es_ES)</li>
+</td>
+</tr>
+</table>
+
+<p>Localized UI strings match the locales that are accessible
+through Settings.</p>
+
+<h2 id="skins">Emulator Skins</h2>
+
+<p>The downloadable platform includes a set of emulator skins that you can use
+for modeling your application in different screen sizes and resolutions. The
+emulator skins are:</p>
+
+<ul>
+ <li>
+ QVGA (240x320, low density, small screen)
+ </li>
+ <li>
+ WQVGA (240x400, low density, normal screen)
+ </li>
+ <li>
+ FWQVGA (240x432, low density, normal screen)
+ </li>
+ <li>
+ HVGA (320x480, medium density, normal screen)
+ </li>
+ <li>
+ WVGA800 (480x800, high density, normal screen)
+ </li>
+ <li>
+ WVGA854 (480x854 high density, normal screen)
+ </li>
+</ul>
+
+<p>For more information about how to develop an application that displays
+and functions properly on all Android-powered devices, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
+
+<h2 id="api">Framework API</h2>
+
+<p>The sections below provide information about changes made to the application
+framework API provided by the Android {@sdkPlatformVersion} platform.</p>
+
+
+<h3 id="api-level">API level</h3>
+
+<p>The Android {@sdkPlatformVersion} platform delivers an updated version of
+the framework API. The Android {@sdkPlatformVersion} API
+is assigned an integer identifier —
+<strong>{@sdkPlatformApiLevel}</strong> — that is
+stored in the system itself. This identifier, called the "API Level", allows the
+system to correctly determine whether an application is compatible with
+the system, prior to installing the application. </p>
+
+<p>To use APIs introduced in Android {@sdkPlatformVersion} in your
+application, you need to set the proper value, "{@sdkPlatformApiLevel}", in the
+<code>android:minSdkVersion</code> attributes of the <code><uses-sdk></code>
+element in your application's manifest. </p>
+
+<p>For more information about how to use API Level, see the <a
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
+
+
+<h3 id="api-changes">API changes summary</h3>
+
+<p>The sections below summarize the changes to the application framework and its APIs.</p>
+
+<h4 id="install-loc">App Installation on External Storage Media</h4>
+
+<p>The Android platform now allows applications to request installation onto the
+device's external storage media (such as the SD card), as an alternative to
+installation onto the device's internal memory. </p>
+
+<p>Application developers can express the preferred installation location for
+their applications by means of a new attribute of <code><manifest></code>
+in the manifest file, <a
+href="{@docRoot}guide/topics/manifest/manifest-element.html#install"><code>
+android:installLocation</code></a>. The attribute supports three values:
+<code>"internalOnly"</code>, <code>"preferExternal"</code>, and
+<code>"auto"</code>. At install time, the system checks the value of
+<code>android:installLocation</code> and installs the application
+<code>.apk</code> according to the preferred location, if possible. If the
+application has requested external installation, the system installs it into a
+private, encrypted partition in the external media. Once an application .apk is
+installed externally, the system lets the user change the storage location of
+the .apk and move it onto the device's internal memory if needed (and vice
+versa), through Manage Applications in the user settings.</p>
+
+<p>By default, the system installs all applications onto the device's internal
+memory, except for those that explicitly request external installation. This
+means that the system will always install legacy applications onto internal
+memory, since they do not have access to the
+<code>android:installLocation</code> attribute. However, it is possible to
+configure and compile a legacy application such that it is installed internally
+on older versions of the platform and externally on Android 2.2 and later
+platforms, if necessary. </p>
+
+<p>Note that requesting installation onto the device's external media is not
+suitable for all applications, particularly because the external media may be
+removable and unmounting/remounting may disrupt the user experience and system
+settings.</p>
+
+<p>For more information about setting a preferred install location for your
+application, including a discussion of what types of applications should and
+should not request external installation, please read the <a
+href="{@docRoot}guide/appendix/install-location.html">App Install Location</a>
+document. </p>
+
+<h4 id="backup-manager">Backup manager</h4>
+
+<p>The platform now provides a generalized backup manager facility that
+applications can use to backup and restore user data, to ensure that users can
+maintain their data when switching devices or reinstalling the application. The
+backup manager handles the work of transporting the application data to and from
+the backup storage area in the cloud. The backup manager can store any type of
+data, from arbitrary data to files, and manages backup and restore operations
+in an atomic manner. </p>
+
+<p>Any application can use the backup manager to save and restore data. To do
+so, the application instantiates a {@link android.app.backup.BackupManager} and
+uses its methods to trigger a new backup or restore operation. The application
+must also create a subclass of {@link android.app.backup.BackupAgent} and
+implement its methods to handle calls from the backup manager to get data for
+backup and provide data to restore
+({@link android.app.backup.BackupAgent#onBackup(android.os.ParcelFileDescriptor, android.app.backup.BackupDataOutput, android.os.ParcelFileDescriptor) onBackup()}
+and {@link android.app.backup.BackupAgent#onRestore(android.app.backup.BackupDataInput, int, android.os.ParcelFileDescriptor) onRestore()}).
+A simple implementation of a BackupAgent useful for backing up preferences
+and files is available by using {@link android.app.backup.BackupAgentHelper}.
+For more information, see <a
+href="{@docRoot}guide/topics/topics/data/backup.html">Data Backup</a>.</p>
+
+<h4>Graphics</h4>
+
+<ul>
+<li>New OpenGL ES 2.0 APIs in {@link android.opengl.GLES20 android.opengl.GLES20}.</li>
+<li>New {@link android.opengl.ETC1}, {@link android.opengl.ETC1Util}, and {@link android.opengl.ETC1Util.ETC1Texture} classes and utility methods for using ETC1 for texture compression.</li>
+<li>New {@link android.graphics.ImageFormat} class.</li>
+<li>New {@link android.graphics.YuvImage YUV image format API} to enable compression from YUV to JPEG and manipulation of YUV data.</li>
+</ul>
+
+<h4>Media</h4>
+
+<ul>
+<li>New APIs in {@link android.media.AudioManager android.media.AudioManager} for managing audio focus, transport control, transient loss of audio focus, ducking.</li>
+<li>New broadcast intent for routing audio to SCO — {@link android.media.AudioManager#ACTION_SCO_AUDIO_STATE_CHANGED} with extras indicating new state.</li>
+<li>New APIs in {@link android.media.SoundPool} to detect completion of sound-loading.</li>
+<li>New APIs in {@link android.media.SoundPool} for auto pause and resume.</li>
+<li>New APIs in {@link android.media.MediaRecorder} for specifying audio settings for number of channels, encoding and sampling rates, sampling rate.</li>
+<li>New APIs for adding files to the media database, so that they are automatically scanned. See {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[], OnScanCompletedListener) MediaScannerConnection.scanFile} and {@link android.media.MediaScannerConnection.OnScanCompletedListener MediaScannerConnection.OnScanCompletedListener}.</li>
+</ul>
+
+<h4>Third-party voice recognition engines</h4>
+
+<ul>
+<li>The platform now provides a {@link android.speech.RecognitionService} base class that lets third-party developers create plug-in recognition engines. </li>
+<li>New {@link android.speech.RecognitionListener} interface to receive callbacks.</li>
+<li>New {@link android.speech.RecognizerIntent} extras that let a requester app specify details as preferred language, minimum length in milliseconds, and so on.</li>
+</ul>
+
+<h4>Camera and camcorder</h4>
+
+<ul>
+<li>Changes to camera preview API to improve efficieny of preview pipeline. </li>
+<li>New display orientation for camera (it can now work in portrait orientation).</li>
+<li>New APIs in {@link android.hardware.Camera android.hardware.Camera} for managing zoom level.</li>
+<li>New APIs {@link android.hardware.Camera.Parameters android.hardware.Camera.Parameters} for querying and setting device camera settings such as focal length, exposure, zoom level, view angle, and others.</li>
+<li>New {@link android.media.ThumbnailUtils thumbnail} utility for video and image thumbnails.</li>
+<li>New {@link android.media.CamcorderProfile} and {@link android.media.CamcorderProfile} classes enable apps to determine device hardware camera capablities.</li>
+<li>New support in {@link android.media.ExifInterface android.media.ExifInterface} for retrieving GPS and focal length.</li>
+</ul>
+
+<h4>Device policy manager</h4>
+
+<p>New device policy management APIs allow developers to write "device administrator" applications that can control security features of the device, such as the minimum password strength, data wipe, and so on. Users can select the administrators that are enabled on their devices. For more information, see the {@link android.app.admin android.app.admin} classees.</p>
+
+<h4>UI Framework</h4>
+
+<ul>
+<li>New UI modes "car mode" and "night mode" and {@link android.app.UiModeManager} let applications adjust their application UI for specific user modes. </li>
+<li>New {@link android.view.ScaleGestureDetector} that lets Views detect and handle transformation gestures that involve more than one pointer (multitouch) using the supplied MotionEvents. </li>
+<li>Improvements in the way that multitouch events are reported in {@link android.view.MotionEvent} objects.</li>
+<li>The layout attribute <code>fill_parent</code> is renamed to <code>match_parent</code>. This affects both XML and Java code (see {@link android.view.ViewGroup.LayoutParams}). Note that the platform will continue to honor uses of <code>fill_parent</code> in legacy applications. </li>
+<li>New layout attributes {@link android.R.attr#tabStripEnabled}, {@link android.R.attr#tabStripRight}, and {@link android.R.attr#tabStripLeft} let developers customize the bottom strip of TabWidgets.</li>
+<li>Better support for managed dialogs in Activity.</li> application data (and applications)
+</ul>
+
+<h4>Accounts and Sync</h4>
+
+<ul>
+<li>New method {@link android.content.ContentResolver#addPeriodicSync(Account, String, Bundle, long) AddPeriodicSync()} lets you schedule a periodic sync with a specific account, authority, and extras at the given frequency.</li>
+</ul>
+
+<h4>New manifest elements and attributes</h4>
+
+<ul>
+<li>For specifying the application's preferred install location (see <a href="#install-loc">App Installation on External Storage Media</a>, above):
+
+<ul>
+ <li>New <code>android:installLocation</code> attribute of the <code><manifest></code> element. Specifies the default install location defined by an application.</li>
+</ul>
+</li>
+
+<li>For managing user data backup (see <a href="#backup-manager">Backup manager</a>, above, for more information):
+
+<ul>
+ <li> New <code>android:backupAgent</code> attribute of the
+<code><application></code> element. Specifies the component name of the
+BackupAgent subclass provided by the application to handle backup/restore
+operations, if any.</li>
+ <li> New <code>android:restoreAnyVersion</code> attribute of the
+<code><application></code> element. Boolean value that indicates whether
+the application is prepared to attempt a restore of any backed-up dataset, even
+if the backup is apparently from a newer version of the application than is
+currently installed on the device.</li>
+</ul>
+</li>
+
+<li>For managing the platform's JIT compiler:
+
+<ul>
+<li>New <code>android:vmSafeMode</code> attribute of the <code><application></code> element. Boolean value that specifies whether to disable JIT compiler optimizations when running the application.</li>
+</ul>
+</li>
+</ul>
+
+<h4>Permissions</h4>
+
+<ul>
+<li><code>android.permission.BIND_DEVICE_ADMIN</code> — Any device administration broadcast receiver must require this permission, to ensure that only the system can interact with it.</li>
+<li><code>android.permission.KILL_BACKGROUND_PROCESSES</code> — Allows an application to call {@link android.app.ActivityManager#killBackgroundProcesses(String)}.
+<li><code>android.permission.BIND_WALLPAPER</code> — Any {@link android.service.wallpaper.WallpaperService} must require this permission, to ensure that only the system can interact with it.</li>
+<li><code>android.permission.SET_TIME</code> — Allows an application to set the system time.</li>
+</ul>
+
+<!--
+<h3 id="behavior-changes">Behavior changes</h3>
+
+What did change is that android:process and android:sharedUserId can now be a reference to a resource (instead of just a literal).
+<h3 id="bug-fixes">Bug fixes</h3>
+-->
+
+<h3 id="api-diff">API differences report</h3>
+
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API
+Level {@sdkPlatformApiLevel}), see the <a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
+Differences Report</a>.</p>
+
diff --git a/docs/html/sdk/api_diff/8/changes.html b/docs/html/sdk/api_diff/8/changes.html
index f46a8b6..20804fe 100644
--- a/docs/html/sdk/api_diff/8/changes.html
+++ b/docs/html/sdk/api_diff/8/changes.html
@@ -4,7 +4,7 @@
<meta name="generator" content="JDiff v1.1.0">
<!-- Generated by the JDiff Javadoc doclet -->
<!-- (http://www.jdiff.org) -->
-<!-- on Fri May 07 16:29:16 PDT 2010 -->
+<!-- on Tue May 11 19:22:44 PDT 2010 -->
<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
<TITLE>
diff --git a/docs/html/sdk/api_diff/8/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/8/changes/alldiffs_index_additions.html
index b4bd6f7..303aeb3 100644
--- a/docs/html/sdk/api_diff/8/changes/alldiffs_index_additions.html
+++ b/docs/html/sdk/api_diff/8/changes/alldiffs_index_additions.html
@@ -1523,9 +1523,6 @@
<A HREF="pkg_android.os.html#RecoverySystem" class="hiddenlink" target="rightframe"><b>RecoverySystem</b></A><br>
<!-- Class RecoverySystem.ProgressListener -->
<A HREF="pkg_android.os.html#RecoverySystem.ProgressListener" class="hiddenlink" target="rightframe"><b><i>RecoverySystem.ProgressListener</i></b></A><br>
-<!-- Method registerAudioFocusListener -->
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>registerAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<!-- Method registerMediaButtonEventReceiver -->
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>registerMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
@@ -1951,9 +1948,6 @@
<!-- Field UNKNOWN_STRING -->
<nobr><A HREF="android.provider.MediaStore.html#android.provider.MediaStore.UNKNOWN_STRING" class="hiddenlink" target="rightframe">UNKNOWN_STRING</A>
</nobr><br>
-<!-- Method unregisterAudioFocusListener -->
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>unregisterAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<!-- Method unregisterMediaButtonEventReceiver -->
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>unregisterMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
diff --git a/docs/html/sdk/api_diff/8/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/8/changes/alldiffs_index_all.html
index 3257470..278625a 100644
--- a/docs/html/sdk/api_diff/8/changes/alldiffs_index_all.html
+++ b/docs/html/sdk/api_diff/8/changes/alldiffs_index_all.html
@@ -2062,9 +2062,6 @@
<A HREF="pkg_android.os.html#RecoverySystem" class="hiddenlink" target="rightframe"><b>RecoverySystem</b></A><br>
<!-- Class RecoverySystem.ProgressListener -->
<A HREF="pkg_android.os.html#RecoverySystem.ProgressListener" class="hiddenlink" target="rightframe"><b><i>RecoverySystem.ProgressListener</i></b></A><br>
-<!-- Method registerAudioFocusListener -->
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>registerAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<!-- Method registerMediaButtonEventReceiver -->
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>registerMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
@@ -2571,9 +2568,6 @@
<!-- Field UNKNOWN_STRING -->
<nobr><A HREF="android.provider.MediaStore.html#android.provider.MediaStore.UNKNOWN_STRING" class="hiddenlink" target="rightframe">UNKNOWN_STRING</A>
</nobr><br>
-<!-- Method unregisterAudioFocusListener -->
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>unregisterAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<!-- Method unregisterMediaButtonEventReceiver -->
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>unregisterMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
diff --git a/docs/html/sdk/api_diff/8/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/8/changes/android.Manifest.permission.html
index b6c6e92..2b79d42 100644
--- a/docs/html/sdk/api_diff/8/changes/android.Manifest.permission.html
+++ b/docs/html/sdk/api_diff/8/changes/android.Manifest.permission.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.R.anim.html b/docs/html/sdk/api_diff/8/changes/android.R.anim.html
index 5e0a9b9..0d1118e 100644
--- a/docs/html/sdk/api_diff/8/changes/android.R.anim.html
+++ b/docs/html/sdk/api_diff/8/changes/android.R.anim.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.R.attr.html b/docs/html/sdk/api_diff/8/changes/android.R.attr.html
index 49a5b00..0a1193c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.R.attr.html
+++ b/docs/html/sdk/api_diff/8/changes/android.R.attr.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.R.id.html b/docs/html/sdk/api_diff/8/changes/android.R.id.html
index 4e37aa3..e2845c4 100644
--- a/docs/html/sdk/api_diff/8/changes/android.R.id.html
+++ b/docs/html/sdk/api_diff/8/changes/android.R.id.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.accounts.AccountManager.html b/docs/html/sdk/api_diff/8/changes/android.accounts.AccountManager.html
index 6d1e4b2..1380d97 100644
--- a/docs/html/sdk/api_diff/8/changes/android.accounts.AccountManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.accounts.AccountManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.Activity.html b/docs/html/sdk/api_diff/8/changes/android.app.Activity.html
index 3e181f8..9c6f336 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.Activity.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.Activity.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.ProcessErrorStateInfo.html b/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.ProcessErrorStateInfo.html
index b97137d..1a9d306 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.ProcessErrorStateInfo.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.ProcessErrorStateInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.html b/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.html
index 796ac35..08897c9 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.ActivityManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.AlarmManager.html b/docs/html/sdk/api_diff/8/changes/android.app.AlarmManager.html
index b59c80e..7c1bad4 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.AlarmManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.AlarmManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.Dialog.html b/docs/html/sdk/api_diff/8/changes/android.app.Dialog.html
index 9c81eca..3cbda33 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.Dialog.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.Dialog.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.app.SearchManager.html b/docs/html/sdk/api_diff/8/changes/android.app.SearchManager.html
index a6d5ff9..e7246ad 100644
--- a/docs/html/sdk/api_diff/8/changes/android.app.SearchManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.app.SearchManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.AbstractThreadedSyncAdapter.html b/docs/html/sdk/api_diff/8/changes/android.content.AbstractThreadedSyncAdapter.html
index 5507fae..bb11780 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.AbstractThreadedSyncAdapter.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.AbstractThreadedSyncAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.ComponentName.html b/docs/html/sdk/api_diff/8/changes/android.content.ComponentName.html
index c1e78613..636d0a1 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.ComponentName.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.ComponentName.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.ContentResolver.html b/docs/html/sdk/api_diff/8/changes/android.content.ContentResolver.html
index 69e4716..5565ed9 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.ContentResolver.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.ContentResolver.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.Context.html b/docs/html/sdk/api_diff/8/changes/android.content.Context.html
index 7f18248..0af8e49 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.Context.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.Context.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.ContextWrapper.html b/docs/html/sdk/api_diff/8/changes/android.content.ContextWrapper.html
index 010cde7..2205266 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.ContextWrapper.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.ContextWrapper.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.Intent.html b/docs/html/sdk/api_diff/8/changes/android.content.Intent.html
index 12eb65c..4872ecc 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.Intent.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.Intent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.SyncResult.html b/docs/html/sdk/api_diff/8/changes/android.content.SyncResult.html
index c5b4107..b4b7884 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.SyncResult.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.SyncResult.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/8/changes/android.content.pm.ActivityInfo.html
index ef9d750..6d406bf 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.pm.ActivityInfo.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.pm.ActivityInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.pm.ApplicationInfo.html b/docs/html/sdk/api_diff/8/changes/android.content.pm.ApplicationInfo.html
index 554e178..2a5d0fe 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.pm.ApplicationInfo.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.pm.ApplicationInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.pm.ComponentInfo.html b/docs/html/sdk/api_diff/8/changes/android.content.pm.ComponentInfo.html
index 1cb101f..ef0b4b3 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.pm.ComponentInfo.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.pm.ComponentInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/8/changes/android.content.pm.PackageManager.html
index 6f7f3e5..369a199 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.pm.PackageManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.pm.PackageManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.content.res.Configuration.html b/docs/html/sdk/api_diff/8/changes/android.content.res.Configuration.html
index ca170b9..7d18172 100644
--- a/docs/html/sdk/api_diff/8/changes/android.content.res.Configuration.html
+++ b/docs/html/sdk/api_diff/8/changes/android.content.res.Configuration.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.database.DatabaseUtils.html b/docs/html/sdk/api_diff/8/changes/android.database.DatabaseUtils.html
index 9ca336d..71d06f3 100644
--- a/docs/html/sdk/api_diff/8/changes/android.database.DatabaseUtils.html
+++ b/docs/html/sdk/api_diff/8/changes/android.database.DatabaseUtils.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteDatabase.html b/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteDatabase.html
index fdf7c5e..069347a 100644
--- a/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteDatabase.html
+++ b/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteDatabase.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteProgram.html b/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteProgram.html
index 92552a6..622a951 100644
--- a/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteProgram.html
+++ b/docs/html/sdk/api_diff/8/changes/android.database.sqlite.SQLiteProgram.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.gesture.Gesture.html b/docs/html/sdk/api_diff/8/changes/android.gesture.Gesture.html
index fa384bd..66b7e23 100644
--- a/docs/html/sdk/api_diff/8/changes/android.gesture.Gesture.html
+++ b/docs/html/sdk/api_diff/8/changes/android.gesture.Gesture.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.gesture.GesturePoint.html b/docs/html/sdk/api_diff/8/changes/android.gesture.GesturePoint.html
index 46c49ed..86bb697 100644
--- a/docs/html/sdk/api_diff/8/changes/android.gesture.GesturePoint.html
+++ b/docs/html/sdk/api_diff/8/changes/android.gesture.GesturePoint.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.gesture.GestureStroke.html b/docs/html/sdk/api_diff/8/changes/android.gesture.GestureStroke.html
index ab12967..55bc9fe 100644
--- a/docs/html/sdk/api_diff/8/changes/android.gesture.GestureStroke.html
+++ b/docs/html/sdk/api_diff/8/changes/android.gesture.GestureStroke.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.graphics.PixelFormat.html b/docs/html/sdk/api_diff/8/changes/android.graphics.PixelFormat.html
index f70e157c..40ca2c7 100644
--- a/docs/html/sdk/api_diff/8/changes/android.graphics.PixelFormat.html
+++ b/docs/html/sdk/api_diff/8/changes/android.graphics.PixelFormat.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.Parameters.html b/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.Parameters.html
index 01e7ed6..13e2cc5 100644
--- a/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.Parameters.html
+++ b/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.Parameters.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.html b/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.html
index c5daaa4..b4e0709 100644
--- a/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.html
+++ b/docs/html/sdk/api_diff/8/changes/android.hardware.Camera.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.hardware.Sensor.html b/docs/html/sdk/api_diff/8/changes/android.hardware.Sensor.html
index 78063ef..4c45340 100644
--- a/docs/html/sdk/api_diff/8/changes/android.hardware.Sensor.html
+++ b/docs/html/sdk/api_diff/8/changes/android.hardware.Sensor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.location.LocationManager.html b/docs/html/sdk/api_diff/8/changes/android.location.LocationManager.html
index a321b4f..ccbc00c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.location.LocationManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.location.LocationManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.AudioManager.html b/docs/html/sdk/api_diff/8/changes/android.media.AudioManager.html
index da73b32..b337b3d 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.AudioManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.AudioManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -97,13 +97,6 @@
</TR>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"></A>
- <nobr><code>void</code> <A HREF="../../../../reference/android/media/AudioManager.html#registerAudioFocusListener(android.media.AudioManager.OnAudioFocusChangeListener)" target="_top"><code>registerAudioFocusListener</code></A>(<code>OnAudioFocusChangeListener</code>)</nobr>
- </TD>
- <TD> </TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)"></A>
<nobr><code>void</code> <A HREF="../../../../reference/android/media/AudioManager.html#registerMediaButtonEventReceiver(android.content.ComponentName)" target="_top"><code>registerMediaButtonEventReceiver</code></A>(<code>ComponentName</code>)</nobr>
</TD>
@@ -132,13 +125,6 @@
</TR>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"></A>
- <nobr><code>void</code> <A HREF="../../../../reference/android/media/AudioManager.html#unregisterAudioFocusListener(android.media.AudioManager.OnAudioFocusChangeListener)" target="_top"><code>unregisterAudioFocusListener</code></A>(<code>OnAudioFocusChangeListener</code>)</nobr>
- </TD>
- <TD> </TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)"></A>
<nobr><code>void</code> <A HREF="../../../../reference/android/media/AudioManager.html#unregisterMediaButtonEventReceiver(android.content.ComponentName)" target="_top"><code>unregisterMediaButtonEventReceiver</code></A>(<code>ComponentName</code>)</nobr>
</TD>
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.ExifInterface.html b/docs/html/sdk/api_diff/8/changes/android.media.ExifInterface.html
index 862f99d..0f32571 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.ExifInterface.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.ExifInterface.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.MediaRecorder.html b/docs/html/sdk/api_diff/8/changes/android.media.MediaRecorder.html
index ca60132..d0a6263 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.MediaRecorder.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.MediaRecorder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.MediaScannerConnectionClient.html b/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.MediaScannerConnectionClient.html
index 11b8c8f..5ee8da4 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.MediaScannerConnectionClient.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.MediaScannerConnectionClient.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.html b/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.html
index 79c8f0c..5d5070c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.MediaScannerConnection.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.media.SoundPool.html b/docs/html/sdk/api_diff/8/changes/android.media.SoundPool.html
index 3c24f5a..39f81fd 100644
--- a/docs/html/sdk/api_diff/8/changes/android.media.SoundPool.html
+++ b/docs/html/sdk/api_diff/8/changes/android.media.SoundPool.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.net.ConnectivityManager.html b/docs/html/sdk/api_diff/8/changes/android.net.ConnectivityManager.html
index f04a891..9030e2d 100644
--- a/docs/html/sdk/api_diff/8/changes/android.net.ConnectivityManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.net.ConnectivityManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.net.SSLCertificateSocketFactory.html b/docs/html/sdk/api_diff/8/changes/android.net.SSLCertificateSocketFactory.html
index b49793e..74c1bbb 100644
--- a/docs/html/sdk/api_diff/8/changes/android.net.SSLCertificateSocketFactory.html
+++ b/docs/html/sdk/api_diff/8/changes/android.net.SSLCertificateSocketFactory.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.net.http.SslCertificate.html b/docs/html/sdk/api_diff/8/changes/android.net.http.SslCertificate.html
index d71e1e4..5a8fe4f 100644
--- a/docs/html/sdk/api_diff/8/changes/android.net.http.SslCertificate.html
+++ b/docs/html/sdk/api_diff/8/changes/android.net.http.SslCertificate.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.opengl.GLSurfaceView.html b/docs/html/sdk/api_diff/8/changes/android.opengl.GLSurfaceView.html
index 25c5a3cc..8679a61 100644
--- a/docs/html/sdk/api_diff/8/changes/android.opengl.GLSurfaceView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.opengl.GLSurfaceView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.opengl.Matrix.html b/docs/html/sdk/api_diff/8/changes/android.opengl.Matrix.html
index ace87ef..9288e5c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.opengl.Matrix.html
+++ b/docs/html/sdk/api_diff/8/changes/android.opengl.Matrix.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/8/changes/android.os.Build.VERSION_CODES.html
index 0ba8e22..4f86bca 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.Build.VERSION_CODES.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.Build.VERSION_CODES.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.Build.html b/docs/html/sdk/api_diff/8/changes/android.os.Build.html
index 7f0bbe9..d6a3fd3 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.Build.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.Build.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.Bundle.html b/docs/html/sdk/api_diff/8/changes/android.os.Bundle.html
index 3c80fed..091f483 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.Bundle.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.Bundle.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.Debug.html b/docs/html/sdk/api_diff/8/changes/android.os.Debug.html
index 588b5ed..e5a57b3 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.Debug.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.Debug.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.Environment.html b/docs/html/sdk/api_diff/8/changes/android.os.Environment.html
index 9b34806..b803614 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.Environment.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.Environment.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.os.PowerManager.html b/docs/html/sdk/api_diff/8/changes/android.os.PowerManager.html
index e627a25..0fd9c9e 100644
--- a/docs/html/sdk/api_diff/8/changes/android.os.PowerManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.os.PowerManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.Browser.html b/docs/html/sdk/api_diff/8/changes/android.provider.Browser.html
index e451780..b75b7a0 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.Browser.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.Browser.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.CallLog.Calls.html b/docs/html/sdk/api_diff/8/changes/android.provider.CallLog.Calls.html
index 88afd7f..ab8dbae 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.CallLog.Calls.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.CallLog.Calls.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.Contacts.PresenceColumns.html b/docs/html/sdk/api_diff/8/changes/android.provider.Contacts.PresenceColumns.html
index 18760c9..8a216d7 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.Contacts.PresenceColumns.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.Contacts.PresenceColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.Groups.html b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.Groups.html
index fa84094..f8f0e2f 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.Groups.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.Groups.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.RawContacts.html b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.RawContacts.html
index a8fb75e..011a590 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.RawContacts.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.RawContacts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.StatusColumns.html b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.StatusColumns.html
index c82ca13..970ce5e 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.StatusColumns.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.ContactsContract.StatusColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.AudioColumns.html b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.AudioColumns.html
index ab4db49..ed9fd8d 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.AudioColumns.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.AudioColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.Playlists.Members.html b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.Playlists.Members.html
index c878708..9c0ab20 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.Playlists.Members.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Audio.Playlists.Members.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Images.Thumbnails.html b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Images.Thumbnails.html
index 0fcfaac..999ae40 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Images.Thumbnails.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Images.Thumbnails.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Video.Thumbnails.html b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Video.Thumbnails.html
index 12bb69b..2ffd079 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Video.Thumbnails.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.Video.Thumbnails.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.html b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.html
index 7348fbe..2aab1e8 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.MediaStore.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.Secure.html
index 4c616ce..7b89ab1 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.Secure.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.Secure.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.System.html b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.System.html
index 94b90ee..81dd481 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.System.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.System.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.html b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.html
index 5935078..c78568c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.provider.Settings.html
+++ b/docs/html/sdk/api_diff/8/changes/android.provider.Settings.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.speech.RecognizerIntent.html b/docs/html/sdk/api_diff/8/changes/android.speech.RecognizerIntent.html
index 59448ca..e70defc 100644
--- a/docs/html/sdk/api_diff/8/changes/android.speech.RecognizerIntent.html
+++ b/docs/html/sdk/api_diff/8/changes/android.speech.RecognizerIntent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.Engine.html b/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.Engine.html
index e273ba6..0219ce2 100644
--- a/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.Engine.html
+++ b/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.Engine.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.html b/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.html
index 5a0f406..8bcd351 100644
--- a/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.html
+++ b/docs/html/sdk/api_diff/8/changes/android.speech.tts.TextToSpeech.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.telephony.TelephonyManager.html b/docs/html/sdk/api_diff/8/changes/android.telephony.TelephonyManager.html
index 0a4d76f..f899475 100644
--- a/docs/html/sdk/api_diff/8/changes/android.telephony.TelephonyManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.telephony.TelephonyManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.test.ActivityInstrumentationTestCase2.html b/docs/html/sdk/api_diff/8/changes/android.test.ActivityInstrumentationTestCase2.html
index bd05119..97023e6 100644
--- a/docs/html/sdk/api_diff/8/changes/android.test.ActivityInstrumentationTestCase2.html
+++ b/docs/html/sdk/api_diff/8/changes/android.test.ActivityInstrumentationTestCase2.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.test.mock.MockContext.html b/docs/html/sdk/api_diff/8/changes/android.test.mock.MockContext.html
index b36e533..d2241eb 100644
--- a/docs/html/sdk/api_diff/8/changes/android.test.mock.MockContext.html
+++ b/docs/html/sdk/api_diff/8/changes/android.test.mock.MockContext.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.test.mock.MockPackageManager.html b/docs/html/sdk/api_diff/8/changes/android.test.mock.MockPackageManager.html
index 8c7eb99..9a90a3c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.test.mock.MockPackageManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.test.mock.MockPackageManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.text.AndroidCharacter.html b/docs/html/sdk/api_diff/8/changes/android.text.AndroidCharacter.html
index f2da8db..0e7788e 100644
--- a/docs/html/sdk/api_diff/8/changes/android.text.AndroidCharacter.html
+++ b/docs/html/sdk/api_diff/8/changes/android.text.AndroidCharacter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.text.util.Rfc822Tokenizer.html b/docs/html/sdk/api_diff/8/changes/android.text.util.Rfc822Tokenizer.html
index d635baa..41cbee6 100644
--- a/docs/html/sdk/api_diff/8/changes/android.text.util.Rfc822Tokenizer.html
+++ b/docs/html/sdk/api_diff/8/changes/android.text.util.Rfc822Tokenizer.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.util.EventLogTags.html b/docs/html/sdk/api_diff/8/changes/android.util.EventLogTags.html
index fd602ab..d0eef8a 100644
--- a/docs/html/sdk/api_diff/8/changes/android.util.EventLogTags.html
+++ b/docs/html/sdk/api_diff/8/changes/android.util.EventLogTags.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.util.Log.html b/docs/html/sdk/api_diff/8/changes/android.util.Log.html
index 1bdd41b..f3266be 100644
--- a/docs/html/sdk/api_diff/8/changes/android.util.Log.html
+++ b/docs/html/sdk/api_diff/8/changes/android.util.Log.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.Display.html b/docs/html/sdk/api_diff/8/changes/android.view.Display.html
index 36428d9..8542008 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.Display.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.Display.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.GestureDetector.html b/docs/html/sdk/api_diff/8/changes/android.view.GestureDetector.html
index f1c87c6..7b7aacf 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.GestureDetector.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.GestureDetector.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.HapticFeedbackConstants.html b/docs/html/sdk/api_diff/8/changes/android.view.HapticFeedbackConstants.html
index 8b46c0f..dfb20ec 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.HapticFeedbackConstants.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.HapticFeedbackConstants.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.MotionEvent.html b/docs/html/sdk/api_diff/8/changes/android.view.MotionEvent.html
index 831ec75..568a205 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.MotionEvent.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.MotionEvent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.VelocityTracker.html b/docs/html/sdk/api_diff/8/changes/android.view.VelocityTracker.html
index 007023e..905da726 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.VelocityTracker.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.VelocityTracker.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.View.html b/docs/html/sdk/api_diff/8/changes/android.view.View.html
index b09bc3b..9f4e648 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.View.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.View.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.ViewConfiguration.html b/docs/html/sdk/api_diff/8/changes/android.view.ViewConfiguration.html
index d9ad09e..fb06822 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.ViewConfiguration.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.ViewConfiguration.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.ViewGroup.LayoutParams.html b/docs/html/sdk/api_diff/8/changes/android.view.ViewGroup.LayoutParams.html
index 705abdf..dd82f12 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.ViewGroup.LayoutParams.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.ViewGroup.LayoutParams.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.WindowManager.LayoutParams.html b/docs/html/sdk/api_diff/8/changes/android.view.WindowManager.LayoutParams.html
index 31a72ca6..ada327e 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.WindowManager.LayoutParams.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.WindowManager.LayoutParams.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.view.animation.Animation.html b/docs/html/sdk/api_diff/8/changes/android.view.animation.Animation.html
index 111839d..e75c000 100644
--- a/docs/html/sdk/api_diff/8/changes/android.view.animation.Animation.html
+++ b/docs/html/sdk/api_diff/8/changes/android.view.animation.Animation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.CacheManager.html b/docs/html/sdk/api_diff/8/changes/android.webkit.CacheManager.html
index f425f1d..3f85e2c 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.CacheManager.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.CacheManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.JsResult.html b/docs/html/sdk/api_diff/8/changes/android.webkit.JsResult.html
index 75faf00..a403bfb 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.JsResult.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.JsResult.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.WebChromeClient.html b/docs/html/sdk/api_diff/8/changes/android.webkit.WebChromeClient.html
index 08e1d07..056f613 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.WebChromeClient.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.WebChromeClient.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/8/changes/android.webkit.WebSettings.html
index 3049102..a4c8b8a 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.WebSettings.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.WebSettings.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.WebView.html b/docs/html/sdk/api_diff/8/changes/android.webkit.WebView.html
index 1277a32..8b78a13 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.WebView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.WebView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.webkit.WebViewClient.html b/docs/html/sdk/api_diff/8/changes/android.webkit.WebViewClient.html
index f4bfc96..9ebfd5b 100644
--- a/docs/html/sdk/api_diff/8/changes/android.webkit.WebViewClient.html
+++ b/docs/html/sdk/api_diff/8/changes/android.webkit.WebViewClient.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.AbsListView.html b/docs/html/sdk/api_diff/8/changes/android.widget.AbsListView.html
index d24caeb..e3bb860 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.AbsListView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.AbsListView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.BaseExpandableListAdapter.html b/docs/html/sdk/api_diff/8/changes/android.widget.BaseExpandableListAdapter.html
index ff4c2b0..184cfac 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.BaseExpandableListAdapter.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.BaseExpandableListAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.ImageView.html b/docs/html/sdk/api_diff/8/changes/android.widget.ImageView.html
index 3e8427f..0587c2d 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.ImageView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.ImageView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.ListView.html b/docs/html/sdk/api_diff/8/changes/android.widget.ListView.html
index 8c2c07d..1653521 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.ListView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.ListView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/8/changes/android.widget.RemoteViews.html
index dd33313..c18470b 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.RemoteViews.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.RemoteViews.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.TabWidget.html b/docs/html/sdk/api_diff/8/changes/android.widget.TabWidget.html
index c358dfb..5f23961 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.TabWidget.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.TabWidget.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/android.widget.VideoView.html b/docs/html/sdk/api_diff/8/changes/android.widget.VideoView.html
index 1cf1de7..2002f9b 100644
--- a/docs/html/sdk/api_diff/8/changes/android.widget.VideoView.html
+++ b/docs/html/sdk/api_diff/8/changes/android.widget.VideoView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/changes-summary.html b/docs/html/sdk/api_diff/8/changes/changes-summary.html
index 70d16ff7..f5fa7e6 100644
--- a/docs/html/sdk/api_diff/8/changes/changes-summary.html
+++ b/docs/html/sdk/api_diff/8/changes/changes-summary.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/dalvik.bytecode.Opcodes.html b/docs/html/sdk/api_diff/8/changes/dalvik.bytecode.Opcodes.html
index 279330b..c12ea91 100644
--- a/docs/html/sdk/api_diff/8/changes/dalvik.bytecode.Opcodes.html
+++ b/docs/html/sdk/api_diff/8/changes/dalvik.bytecode.Opcodes.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/dalvik.system.VMDebug.html b/docs/html/sdk/api_diff/8/changes/dalvik.system.VMDebug.html
index 759d8c7..3bec244 100644
--- a/docs/html/sdk/api_diff/8/changes/dalvik.system.VMDebug.html
+++ b/docs/html/sdk/api_diff/8/changes/dalvik.system.VMDebug.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/dalvik.system.Zygote.html b/docs/html/sdk/api_diff/8/changes/dalvik.system.Zygote.html
index d6c9b23..3565aedf 100644
--- a/docs/html/sdk/api_diff/8/changes/dalvik.system.Zygote.html
+++ b/docs/html/sdk/api_diff/8/changes/dalvik.system.Zygote.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.net.DatagramSocketImpl.html b/docs/html/sdk/api_diff/8/changes/java.net.DatagramSocketImpl.html
index 731ce54..f2797c2 100644
--- a/docs/html/sdk/api_diff/8/changes/java.net.DatagramSocketImpl.html
+++ b/docs/html/sdk/api_diff/8/changes/java.net.DatagramSocketImpl.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.nio.charset.Charset.html b/docs/html/sdk/api_diff/8/changes/java.nio.charset.Charset.html
index 51fba71..00459bb 100644
--- a/docs/html/sdk/api_diff/8/changes/java.nio.charset.Charset.html
+++ b/docs/html/sdk/api_diff/8/changes/java.nio.charset.Charset.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.util.ArrayList.html b/docs/html/sdk/api_diff/8/changes/java.util.ArrayList.html
index f8f5017..57a6f01 100644
--- a/docs/html/sdk/api_diff/8/changes/java.util.ArrayList.html
+++ b/docs/html/sdk/api_diff/8/changes/java.util.ArrayList.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.util.HashMap.html b/docs/html/sdk/api_diff/8/changes/java.util.HashMap.html
index 4ee9c7d..f80f209 100644
--- a/docs/html/sdk/api_diff/8/changes/java.util.HashMap.html
+++ b/docs/html/sdk/api_diff/8/changes/java.util.HashMap.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.util.regex.Matcher.html b/docs/html/sdk/api_diff/8/changes/java.util.regex.Matcher.html
index ed85282..cde54ef 100644
--- a/docs/html/sdk/api_diff/8/changes/java.util.regex.Matcher.html
+++ b/docs/html/sdk/api_diff/8/changes/java.util.regex.Matcher.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/java.util.regex.Pattern.html b/docs/html/sdk/api_diff/8/changes/java.util.regex.Pattern.html
index b38c93a..04ccbc1 100644
--- a/docs/html/sdk/api_diff/8/changes/java.util.regex.Pattern.html
+++ b/docs/html/sdk/api_diff/8/changes/java.util.regex.Pattern.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/javax.xml.XMLConstants.html b/docs/html/sdk/api_diff/8/changes/javax.xml.XMLConstants.html
index b4c7fe8..5b75dcc 100644
--- a/docs/html/sdk/api_diff/8/changes/javax.xml.XMLConstants.html
+++ b/docs/html/sdk/api_diff/8/changes/javax.xml.XMLConstants.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilder.html b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilder.html
index 424b6a4..3b0320e 100644
--- a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilder.html
+++ b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilderFactory.html b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilderFactory.html
index b524428..db4f0a3 100644
--- a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilderFactory.html
+++ b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.DocumentBuilderFactory.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParser.html b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParser.html
index eab0035..48cb76d 100644
--- a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParser.html
+++ b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParser.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParserFactory.html b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParserFactory.html
index a0e70d4..f36f63f 100644
--- a/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParserFactory.html
+++ b/docs/html/sdk/api_diff/8/changes/javax.xml.parsers.SAXParserFactory.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/8/changes/jdiff_statistics.html
index 8e86481..d0eb78b 100644
--- a/docs/html/sdk/api_diff/8/changes/jdiff_statistics.html
+++ b/docs/html/sdk/api_diff/8/changes/jdiff_statistics.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -110,10 +110,10 @@
</TR>
<TR>
<TD>Methods</TD>
- <TD ALIGN="right">208</TD>
+ <TD ALIGN="right">206</TD>
<TD ALIGN="right">37</TD>
<TD ALIGN="right">3</TD>
- <TD ALIGN="right">248</TD>
+ <TD ALIGN="right">246</TD>
</TR>
<TR>
<TD>Fields</TD>
@@ -124,10 +124,10 @@
</TR>
<TR>
<TD style="background-color:#FAFAFA"><b>Total</b></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>477</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>475</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>225</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>33</strong></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>735</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>733</strong></TD>
</TR>
</TABLE>
<br>
@@ -445,11 +445,6 @@
</TR>
<TR>
<TD ALIGN="center">11</TD>
- <TD><A HREF="android.media.AudioManager.html">
-android.media.AudioManager</A></TD>
-</TR>
-<TR>
- <TD ALIGN="center">11</TD>
<TD><A HREF="android.gesture.GesturePoint.html">
android.gesture.GesturePoint</A></TD>
</TR>
@@ -484,6 +479,11 @@
android.view.ViewGroup.LayoutParams</A></TD>
</TR>
<TR>
+ <TD ALIGN="center">10</TD>
+ <TD><A HREF="android.media.AudioManager.html">
+android.media.AudioManager</A></TD>
+</TR>
+<TR>
<TD ALIGN="center">9</TD>
<TD><A HREF="android.content.ContentResolver.html">
android.content.ContentResolver</A></TD>
diff --git a/docs/html/sdk/api_diff/8/changes/methods_index_additions.html b/docs/html/sdk/api_diff/8/changes/methods_index_additions.html
index 2b4d83f..822c43b 100644
--- a/docs/html/sdk/api_diff/8/changes/methods_index_additions.html
+++ b/docs/html/sdk/api_diff/8/changes/methods_index_additions.html
@@ -676,8 +676,6 @@
(<code>String</code>)</A></nobr><br>
<nobr><A HREF="android.hardware.Camera.html#android.hardware.Camera.reconnect_added()" class="hiddenlink" target="rightframe"><b>reconnect</b>
()</A></nobr><br>
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>registerAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>registerMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
<nobr><A HREF="android.content.ContentResolver.html#android.content.ContentResolver.removePeriodicSync_added(android.accounts.Account, java.lang.String, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>removePeriodicSync</b>
@@ -869,8 +867,6 @@
<a href="#W"><font size="-2">W</font></a>
<a href="#topheader"><font size="-2">TOP</font></a>
<p><div style="line-height:1.5em;color:black">
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>unregisterAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>unregisterMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
<nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.updateWithOnConflict_added(java.lang.String, android.content.ContentValues, java.lang.String, java.lang.String[], int)" class="hiddenlink" target="rightframe"><b>updateWithOnConflict</b>
diff --git a/docs/html/sdk/api_diff/8/changes/methods_index_all.html b/docs/html/sdk/api_diff/8/changes/methods_index_all.html
index 5a81efa..91d79f8 100644
--- a/docs/html/sdk/api_diff/8/changes/methods_index_all.html
+++ b/docs/html/sdk/api_diff/8/changes/methods_index_all.html
@@ -801,8 +801,6 @@
(<code>String</code>)</A></nobr><br>
<nobr><A HREF="android.hardware.Camera.html#android.hardware.Camera.reconnect_added()" class="hiddenlink" target="rightframe"><b>reconnect</b>
()</A></nobr><br>
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>registerAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>registerMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
<nobr><A HREF="android.content.ContentResolver.html#android.content.ContentResolver.removePeriodicSync_added(android.accounts.Account, java.lang.String, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>removePeriodicSync</b>
@@ -1009,8 +1007,6 @@
<a href="#W"><font size="-2">W</font></a>
<a href="#topheader"><font size="-2">TOP</font></a>
<p><div style="line-height:1.5em;color:black">
-<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)" class="hiddenlink" target="rightframe"><b>unregisterAudioFocusListener</b>
-(<code>OnAudioFocusChangeListener</code>)</A></nobr><br>
<nobr><A HREF="android.media.AudioManager.html#android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)" class="hiddenlink" target="rightframe"><b>unregisterMediaButtonEventReceiver</b>
(<code>ComponentName</code>)</A></nobr><br>
<nobr><A HREF="android.database.sqlite.SQLiteDatabase.html#android.database.sqlite.SQLiteDatabase.updateWithOnConflict_added(java.lang.String, android.content.ContentValues, java.lang.String, java.lang.String[], int)" class="hiddenlink" target="rightframe"><b>updateWithOnConflict</b>
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Attr.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Attr.html
index 868751b..860375b 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Attr.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Attr.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMException.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMException.html
index 85b5d02..c7e82fb 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMException.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMException.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMImplementation.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMImplementation.html
index a82bb1d..4c498fa 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMImplementation.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.DOMImplementation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Document.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Document.html
index 63171130..8eaf593 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Document.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Document.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Element.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Element.html
index d4a4e0a..bef9622 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Element.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Element.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Entity.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Entity.html
index 97b0225..07cc42c 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Entity.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Entity.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.NamedNodeMap.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.NamedNodeMap.html
index 37a80d1..08662fd 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.NamedNodeMap.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.NamedNodeMap.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Node.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Node.html
index 7818487..9c9e968 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Node.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Node.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Text.html b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Text.html
index e31b254..eb8a239 100644
--- a/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Text.html
+++ b/docs/html/sdk/api_diff/8/changes/org.w3c.dom.Text.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.accounts.html b/docs/html/sdk/api_diff/8/changes/pkg_android.accounts.html
index fcf1e49..7f2c3e0 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.accounts.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.accounts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.app.html b/docs/html/sdk/api_diff/8/changes/pkg_android.app.html
index d6c005d..892b454 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.app.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.app.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.content.html b/docs/html/sdk/api_diff/8/changes/pkg_android.content.html
index 4ce2a7b..d0a8e32 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.content.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.content.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/8/changes/pkg_android.content.pm.html
index 9fe0480..29f6c7a 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.content.pm.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.content.pm.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.content.res.html b/docs/html/sdk/api_diff/8/changes/pkg_android.content.res.html
index 581a136..055d42a 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.content.res.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.content.res.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.database.html b/docs/html/sdk/api_diff/8/changes/pkg_android.database.html
index 64ff8ef..dece819 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.database.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.database.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.database.sqlite.html b/docs/html/sdk/api_diff/8/changes/pkg_android.database.sqlite.html
index 2caf99f..6f0d2ba 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.database.sqlite.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.database.sqlite.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.gesture.html b/docs/html/sdk/api_diff/8/changes/pkg_android.gesture.html
index 0dbee8a..28ec9d1 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.gesture.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.gesture.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/8/changes/pkg_android.graphics.html
index cb72a96..aafb0e0 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.graphics.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.graphics.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/8/changes/pkg_android.hardware.html
index 990af48..13d1c3a 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.hardware.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.hardware.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.html b/docs/html/sdk/api_diff/8/changes/pkg_android.html
index 4460b8e..c100283 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.location.html b/docs/html/sdk/api_diff/8/changes/pkg_android.location.html
index 5472cd8..a4244d2 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.location.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.location.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.media.html b/docs/html/sdk/api_diff/8/changes/pkg_android.media.html
index f9f25cd..4289206 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.media.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.media.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.net.html b/docs/html/sdk/api_diff/8/changes/pkg_android.net.html
index a262059..b771a2b 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.net.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.net.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.net.http.html b/docs/html/sdk/api_diff/8/changes/pkg_android.net.http.html
index ea0667e..5b9f5c8 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.net.http.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.net.http.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.opengl.html b/docs/html/sdk/api_diff/8/changes/pkg_android.opengl.html
index 2c7731b..1bea6d9 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.opengl.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.opengl.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.os.html b/docs/html/sdk/api_diff/8/changes/pkg_android.os.html
index 6f9ae39..cf3fc7d 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.os.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.os.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/8/changes/pkg_android.provider.html
index 865e1f0..06db000 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.provider.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.provider.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.speech.html b/docs/html/sdk/api_diff/8/changes/pkg_android.speech.html
index 93b38e3..0ae2978 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.speech.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.speech.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.speech.tts.html b/docs/html/sdk/api_diff/8/changes/pkg_android.speech.tts.html
index 466d4ac..d8368a2 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.speech.tts.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.speech.tts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.telephony.html b/docs/html/sdk/api_diff/8/changes/pkg_android.telephony.html
index 046152d..718df76 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.telephony.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.telephony.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.test.html b/docs/html/sdk/api_diff/8/changes/pkg_android.test.html
index c493eed7..df8b98c 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.test.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.test.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.test.mock.html b/docs/html/sdk/api_diff/8/changes/pkg_android.test.mock.html
index ad79542..344281b 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.test.mock.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.test.mock.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.text.html b/docs/html/sdk/api_diff/8/changes/pkg_android.text.html
index d0ecda0..ae9e9a7 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.text.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.text.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.text.style.html b/docs/html/sdk/api_diff/8/changes/pkg_android.text.style.html
index 62f89bc..6332233 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.text.style.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.text.style.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.text.util.html b/docs/html/sdk/api_diff/8/changes/pkg_android.text.util.html
index 2c53a45..875efa6 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.text.util.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.text.util.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.util.html b/docs/html/sdk/api_diff/8/changes/pkg_android.util.html
index 91cec9d..7803591 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.util.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.util.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.view.animation.html b/docs/html/sdk/api_diff/8/changes/pkg_android.view.animation.html
index 37a05e0..559c118 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.view.animation.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.view.animation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.view.html b/docs/html/sdk/api_diff/8/changes/pkg_android.view.html
index 8b5bcdb..cb5401f 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.view.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.view.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/8/changes/pkg_android.webkit.html
index ac4bfda..038f1451 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.webkit.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.webkit.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/8/changes/pkg_android.widget.html
index bd2fd3a..bfbf096 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_android.widget.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_android.widget.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_dalvik.bytecode.html b/docs/html/sdk/api_diff/8/changes/pkg_dalvik.bytecode.html
index 0244f4a8..943ec6b 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_dalvik.bytecode.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_dalvik.bytecode.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_dalvik.system.html b/docs/html/sdk/api_diff/8/changes/pkg_dalvik.system.html
index 5151889..14aff19 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_dalvik.system.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_dalvik.system.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_java.net.html b/docs/html/sdk/api_diff/8/changes/pkg_java.net.html
index 477a151..510e838 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_java.net.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_java.net.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_java.nio.charset.html b/docs/html/sdk/api_diff/8/changes/pkg_java.nio.charset.html
index 432ec6d..e83a1be 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_java.nio.charset.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_java.nio.charset.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_java.util.html b/docs/html/sdk/api_diff/8/changes/pkg_java.util.html
index fa1f2ea..0d13408 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_java.util.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_java.util.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_java.util.regex.html b/docs/html/sdk/api_diff/8/changes/pkg_java.util.regex.html
index a461e6e..5227e54 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_java.util.regex.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_java.util.regex.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.html b/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.html
index d6a1c25..f0168b6 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.parsers.html b/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.parsers.html
index 9375f5f..9ddbcbb 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.parsers.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_javax.xml.parsers.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/changes/pkg_org.w3c.dom.html b/docs/html/sdk/api_diff/8/changes/pkg_org.w3c.dom.html
index fa10b118..eca49bc0 100644
--- a/docs/html/sdk/api_diff/8/changes/pkg_org.w3c.dom.html
+++ b/docs/html/sdk/api_diff/8/changes/pkg_org.w3c.dom.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2010.05.07 16:29</td>
+ <td class="diffvalue">2010.05.11 19:22</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/8/missingSinces.txt b/docs/html/sdk/api_diff/8/missingSinces.txt
index 4f89900..905b3ef 100644
--- a/docs/html/sdk/api_diff/8/missingSinces.txt
+++ b/docs/html/sdk/api_diff/8/missingSinces.txt
@@ -204,7 +204,6 @@
NO DOC BLOCK: android.content.res.Configuration Method readFromParcel(android.os.Parcel)
NO DOC BLOCK: android.os.PowerManager Method reboot(java.lang.String)
NO DOC BLOCK: android.hardware.Camera Method reconnect()
-NO DOC BLOCK: android.media.AudioManager Method registerAudioFocusListener(android.media.AudioManager.OnAudioFocusChangeListener)
NO DOC BLOCK: android.media.AudioManager Method registerMediaButtonEventReceiver(android.content.ComponentName)
NO DOC BLOCK: android.content.ContentResolver Method removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle)
NO DOC BLOCK: org.w3c.dom.Document Method renameNode(org.w3c.dom.Node, java.lang.String, java.lang.String)
@@ -263,7 +262,6 @@
NO DOC BLOCK: android.hardware.Camera Method stopSmoothZoom()
NO DOC BLOCK: android.widget.VideoView Method suspend()
NO DOC BLOCK: android.text.util.Rfc822Tokenizer Method tokenize(java.lang.CharSequence, java.util.Collection<android.text.util.Rfc822Token>)
-NO DOC BLOCK: android.media.AudioManager Method unregisterAudioFocusListener(android.media.AudioManager.OnAudioFocusChangeListener)
NO DOC BLOCK: android.media.AudioManager Method unregisterMediaButtonEventReceiver(android.content.ComponentName)
NO DOC BLOCK: android.database.sqlite.SQLiteDatabase Method updateWithOnConflict(java.lang.String, android.content.ContentValues, java.lang.String, java.lang.String[], int)
NO DOC BLOCK: android.util.Log Method wtf(java.lang.String, java.lang.String)
diff --git a/docs/html/sdk/api_diff/8/user_comments_for_7_to_8.xml b/docs/html/sdk/api_diff/8/user_comments_for_7_to_8.xml
index c5c69e4..2ad7e83 100644
--- a/docs/html/sdk/api_diff/8/user_comments_for_7_to_8.xml
+++ b/docs/html/sdk/api_diff/8/user_comments_for_7_to_8.xml
@@ -1444,12 +1444,6 @@
</text>
</comment>
<comment>
- <identifier id="android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"/>
- <text>
- InsertCommentsHere
- </text>
-</comment>
-<comment>
<identifier id="android.media.AudioManager.registerMediaButtonEventReceiver_added(android.content.ComponentName)"/>
<text>
InsertCommentsHere
@@ -1474,12 +1468,6 @@
</text>
</comment>
<comment>
- <identifier id="android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"/>
- <text>
- InsertCommentsHere
- </text>
-</comment>
-<comment>
<identifier id="android.media.AudioManager.unregisterMediaButtonEventReceiver_added(android.content.ComponentName)"/>
<text>
InsertCommentsHere
@@ -4437,5 +4425,21 @@
InsertCommentsHere
</text>
</comment>
+<!-- This comment is no longer used
+<comment>
+ <identifier id="android.media.AudioManager.registerAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"/>
+ <text>
+ InsertCommentsHere
+ </text>
+</comment>
+-->
+<!-- This comment is no longer used
+<comment>
+ <identifier id="android.media.AudioManager.unregisterAudioFocusListener_added(android.media.AudioManager.OnAudioFocusChangeListener)"/>
+ <text>
+ InsertCommentsHere
+ </text>
+</comment>
+-->
</comments>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index d3e0a10..57eac1f 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -81,6 +81,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -89,6 +92,31 @@
}
</style>
+<div class="toggleable opened">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
+ADT 0.9.6</a> <em>(March 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>Library projects:</dt>
+<dd>
+<p>The ADT Plugin now supports the use of <em>library projects</em> during
+development, a capability that lets you store shared Android application
+code and resources in a separate development project. You can then reference the
+library project from other Android projects and, at build time, the tools
+compile the shared code and resources as part of the dependent applications.
+More information about this feature is available in the <a
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
+in Eclipse with ADT</a> document. </p>
+<p>If you are not developing in Eclipse, <a
+href="tools-notes.html">SDK Tools r6</a> provides the equivalent library
+project support through the Ant build system.</p>
+</dd>
+</dl>
+ </div>
+</div>
+
<div class="toggleable closed">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index e10c408..d383fde 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,17 +1,17 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_download=android-sdk_r05-windows.zip
-sdk.win_bytes=23449838
-sdk.win_checksum=cc2c51a24e2f876e0fa652e182ef5840
+sdk.win_download=android-sdk_r06-windows.zip
+sdk.win_bytes=
+sdk.win_checksum=
-sdk.mac_download=android-sdk_r05-mac_86.zip
-sdk.mac_bytes=19871714
-sdk.mac_checksum=6fcfeed0e1c36624c926551637eb3308
+sdk.mac_download=android-sdk_r06-mac_86.zip
+sdk.mac_bytes=
+sdk.mac_checksum=
-sdk.linux_download=android-sdk_r05-linux_86.tgz
-sdk.linux_bytes=16208523
-sdk.linux_checksum=1d695d6a31310406f5d49092a1bd9850
+sdk.linux_download=android-sdk_r06-linux_86.tgz
+sdk.linux_bytes=
+sdk.linux_checksum=
@jd:body
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index fa2e712..93c5fb8 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -1,16 +1,16 @@
ndk=true
-ndk.win_download=android-ndk-r3-windows.zip
-ndk.win_bytes=36473391
-ndk.win_checksum=4ce5c93a15f261b6dcade1b69da00902
+ndk.win_download=android-ndk-r4-windows.zip
+ndk.win_bytes=
+ndk.win_checksum=
-ndk.mac_download=android-ndk-r3-darwin-x86.zip
-ndk.mac_bytes=38258228
-ndk.mac_checksum=a083ccc36aa9a3a35404861e7d51d1ae
+ndk.mac_download=android-ndk-r4-darwin-x86.zip
+ndk.mac_bytes=
+ndk.mac_checksum=
-ndk.linux_download=android-ndk-r3-linux-x86.zip
-ndk.linux_bytes=37403241
-ndk.linux_checksum=f3b1700a195aae3a6e9b5637e5c49359
+ndk.linux_download=android-ndk-r4-linux-x86.zip
+ndk.linux_bytes=
+ndk.linux_checksum=
page.title=Android NDK
@jd:body
@@ -38,20 +38,19 @@
}
</script>
<style>
-
.toggleable {
padding: .25em 1em;
-xfont-size:.95em;
}
-
.toggleme {
- xmargin:1em;
padding: 1em 1em 0 2em;
-line-height:1em;
+ line-height:1em;
}
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -63,6 +62,58 @@
<div class="toggleable open">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+Android NDK, Revision 4</a> <em>(May 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>General notes:</dt>
+
+<dd>
+<ul>
+<li>Provides a simplified build system through the new <code>ndk-build</code> build
+command. </li>
+<li>Adds support for easy native debugging of generated machine code through the new
+<code>ndk-gdb</code> command.</li>
+<li>Adds a new Android-specific ABI for ARM-based CPU architectures,
+<code>armeabi-v7a</code>. The new ABI extends the existing <code>armeabi</code>
+ABI to include these CPU instruction set extensions:
+<ul>
+<li>Thumb-2 instructions</li>
+<li>VFP hardware FPU instructions (VFPv3-D16)</li>
+<li>Optional support for ARM Advanced SIMD (NEON) GCC intrinsics and VFPv3-D32.
+Supported by devices such as Verizon Droid, Google Nexus One, and others.</li>
+</ul>
+<li>Adds a new <code>cpufeatures</code> static library (with sources) that lets
+your app detect the host device's CPU features at runtime. Specifically,
+applications can check for ARMv7-A support, as well as VFPv3-D32 and NEON
+support, then provide separate code paths as needed.</li>
+<li>Adds a sample application, <code>hello-neon</code>, that illustrates how to
+use the <code>cpufeatures</code> library to check CPU features and then provide
+an optimized code path using NEON instrinsics, if
+supported by the CPU.</li>
+<li>Lets you generate machine code for either or both of the instruction sets
+supported by the NDK. For example, you can build for both ARMv5 and ARMv7-A
+architectures at the same time and have everything stored to your application's
+final <code>.apk</code>.</li>
+<li>To ensure that your applications are available to users only if their
+devices are capable of running them, Android Market now filters applications
+based on the instruction set information included in your application — no
+action is needed on your part to enable the filtering. Additionally, the Android
+system itself also checks your application at install time and allows the
+installation to continue only if the application provides a library that is
+compiled for the device's CPU architecture.</li>
+<li>Adds support for Android 2.2, including a new stable API for accessing
+the pixel buffers of {@link android.graphics.Bitmap} objects from native
+code.</li>
+</ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
Android NDK, Revision 3</a> <em>(March 2010)</em>
<div class="toggleme">
@@ -142,17 +193,34 @@
<ul>
<li>A set of tools and build files used to generate native code libraries from C
and C++ sources</li>
-<li>A way to embed the corresponding native libraries into application package
-files (.apks) that can be deployed on Android devices</li>
+<li>A way to embed the corresponding native libraries into an application package
+file (<code>.apk</code>) that can be deployed on Android devices</li>
<li>A set of native system headers and libraries that will be supported in all
future versions of the Android platform, starting from Android 1.5 </li>
<li>Documentation, samples, and tutorials</li>
</ul>
-<p>This release of the NDK supports the ARMv5TE machine instruction set and
-provides stable headers for libc (the C library), libm (the Math library),
-OpenGL ES (3D graphics library), the JNI interface, and other libraries, as
-listed in the section below.</p>
+<p>The latest release of the NDK supports these ARM instruction sets:</p>
+<ul>
+<li>ARMv5TE (including Thumb-1 instructions)</li>
+<li>ARMv7-A (including Thumb-2 and VFPv3-D16 instructions, with
+optional support for NEON/VFPv3-D32 instructions)</li>
+</ul>
+
+<p>ARMv5TE machine code will run on all ARM-based Android devices. ARMv7-A will
+run only on devices such as the Verizon Droid or Google Nexus One that have a
+compatible CPU. The main difference between the two instruction sets is that
+ARMv7-A supports hardware FPU, Thumb-2, and NEON instructions. You can target
+either or both of the instruction sets — ARMv5TE is the default, but
+switching to ARMv7-A is as easy as adding a single line to the application's
+Application.mk file, without needing to change anything else in the file. You
+can also build for both architectures at the same time and have everything
+stored in the final <code>.apk</code>. Complete information is provided in the
+CPU-ARCH-ABIS.TXT in the NDK package. </p>
+
+<p>The NDK provides stable headers for libc (the C library), libm (the Math
+library), OpenGL ES (3D graphics library), the JNI interface, and other
+libraries, as listed in the section below.</p>
<p>The NDK will not benefit most applications. As a developer, you will need
to balance its benefits against its drawbacks; notably, using native code does
@@ -184,6 +252,7 @@
<li>libz (Zlib compression) headers</li>
<li>liblog (Android logging) header</li>
<li>OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers</li>
+<li>libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).</li>
<li>A Minimal set of headers for C++ support</li>
</ul>
@@ -224,6 +293,11 @@
by headers in the NDK.</li>
<li>CPU-ARCH-ABIS.TXT — a description of supported CPU architectures
and how to target them. </li>
+<li>CPU-FEATURES.TXT — a description of the <code>cpufeatures</code>
+static library that lets your application code detect the target device's
+CPU family and the optional features at runtime. </li>
+<li>CPU-ARM-NEON.TXT — a description of how to build with optional
+ARM NEON / VFPv3-D32 instructions. </li>
<li>CHANGES.TXT — a complete list of changes to the NDK across all
releases.</li>
</ul>
@@ -268,8 +342,10 @@
<ul>
<li>For all development platforms, GNU Make 3.81 or later is required. Earlier
versions of GNU Make might work but have not been tested.</li>
- <li>For Windows, a recent release of <a
-href="http://www.cygwin.com">Cygwin</a> is required. </li>
+ <li>A recent version of awk (either GNU Awk or Nawk) is also required.</li>
+ <li>For Windows, <a
+href="http://www.cygwin.com">Cygwin</a> 1.7 or higher is required. The NDK
+will <em>not</em> work with Cygwin 1.5 installations.</li>
</ul>
<h4>Android platform compatibility</h4>
@@ -294,7 +370,7 @@
</manifest></pre>
</li>
-<li>Additionally, if you use this NDK to create a native library that uses the
+<li>If you use this NDK to create a native library that uses the
OpenGL ES APIs, the application containing the library can be deployed only to
devices running the minimum platform versions described in the table below.
To ensure compatibility, make sure that your application declares the proper
@@ -310,16 +386,42 @@
<tr><td>OpenGL ES 2.0</td><td>Android 2.0 and higher</td><td><code>android:minSdkVersion="5"</code></td></tr>
</table>
-<p>For more information about API Level and its relationship to Android
+<p>For more information about API Level and its relationship to Android
platform versions, see <a href="{@docRoot}guide/appendix/api-levels.html">
Android API Levels</a>.</p></li>
+
+<li>Additionally, an application using the OpenGL ES APIs should declare a
+<code><uses-feature></code> element in its manifest, with an
+<code>android:glEsVersion</code> attribute that specifies the minimum OpenGl ES
+version required by the application. This ensures that Android Market will show
+your application only to users whose devices are capable of supporting your
+application. For example:
+
+<pre style="margin:1em;"><manifest>
+ ...
+<!-- Declare that the application uses the OpenGL ES 2.0 API and is designed
+ to run only on devices that support OpenGL ES 2.0 or higher. -->
+ <uses-feature android:glEsVersion="0x00020000" />
+ ...
+</manifest></pre>
+
+<p>For more information, see the <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code><uses-feature></code></a>
+documentation.</p></li>
+
+<li>If you use this NDK to create a native library that uses the API to access
+Android {@link android.graphics.Bitmap} pixel buffers, the application
+containing the library can be deployed only to devices running Android 2.2 (API
+level 8) or higher. To ensure compatibility, make sure that your application
+declares <code><uses-sdk android:minSdkVersion="8" /></code>attribute
+value in its manifest.</li>
</ul>
<h2 id="installing">Installing the NDK</h2>
<p>Installing the NDK on your development computer is straightforward and
-involves extracting the NDK from its download package and running a host-setup
-script. </p>
+involves extracting the NDK from its download package. Unlike previous releases,
+there is no need to run a host-setup script.</p>
<p>Before you get started make sure that you have downloaded the latest <a
href="{@docRoot}sdk/index.html">Android SDK</a> and upgraded your applications
@@ -337,21 +439,9 @@
<code>android-ndk-<version></code>. You can rename the NDK directory if
necessary and you can move it to any location on your computer. This
documentation refers to the NDK directory as <code><ndk></code>. </li>
-<li>Open a terminal, change to the NDK directory, and run the host-setup script.
-The script sets up your environment and generates a host configuration file used
-later, when building your shared libraries. The path to the host-setup script
-is:
-
-<p><code><ndk>/build/host-setup.sh</code></p>
-
-<p>If the script completes successfully, it prints a "Host setup complete."
-message. If it fails, it prints instructions that you can follow to correct any
-problems. </p>
-</li>
</ol>
-<p>Once you have run the host-setup script, you are ready start working with the
-NDK. </p>
+<p>You are now ready start working with the NDK. </p>
<h2 id="gettingstarted">Getting Started with the NDK</h2>
@@ -371,17 +461,14 @@
<code><project>/jni/...</code></li>
<li>Create <code><project>/jni/Android.mk</code> to
describe your native sources to the NDK build system</li>
-<li>Create <code><ndk>/apps/<my_app>/Application.mk</code> to
-describe your Android application and native sources it needs to the NDK build
-system. This file sets up the link between an Android SDK application project
-and any number of shared libraries defined in the
-<code><project>/jni/</code> folder and it specifies the path to the
-application project that will receive the shared library built from the
-sources.</li>
-<li>Build your native code by running this make command from the top-level NDK
-directory:
+<li>Optional: Create <code><project>/jni/Application.mk</code>.</li>
+<li>Build your native code by running the 'ndk-build' script from your projet's directory.
+It is located in the top-level NDK directory:
-<p><code>$ make APP=<my_app></code></p>
+<p><pre>
+$ cd <project>
+$ <ndk>/ndk-build
+</pre></p>
<p>The build tools copy the stripped, shared libraries needed by your
application to the proper location in the application's project directory.</p>
@@ -389,7 +476,7 @@
<li>Finally, compile your application using the SDK tools in the usual way. The
SDK build tools will package the shared libraries in the application's
-deployable .apk file. </p></li>
+deployable <code>.apk</code> file. </p></li>
</ol>
@@ -399,7 +486,7 @@
<h2 id="samples">Using the Sample Applications</h2>
-<p>The NDK includes four sample applications that illustrate how to use native
+<p>The NDK includes sample applications that illustrate how to use native
code in your Android applications:</p>
<ul>
@@ -415,36 +502,27 @@
with a {@link android.opengl.GLSurfaceView} object. </li>
<li><code>hello-gl2</code> — a simple application that renders a triangle
using OpenGL ES 2.0 vertex and fragment shaders.</li>
+<li><code>hello-neon</code> — a simple application that shows how to use
+the <code>cpufeatures</code> library to check CPU capabilities at runtime,
+then use NEON intrinsics if supported by the CPU. Specifically, the
+application implements two versions of a tiny benchmark for a FIR filter
+loop, a C version and a NEON-optimized version for devices that support it.</li>
+<li><code>bitmap-plasma</code> — a simple application that demonstrates
+how to access the pixel buffers of Android {@link android.graphics.Bitmap}
+objects from native code, and uses this to generate an old-school "plasma"
+effect. </li>
</ul>
-<p>For each sample, the NDK includes an Android application project, as well as
-the corresponding C source code and the necessary Android.mk and Application.mk
-files. The application projects are provided in
-<code><ndk>/apps/<app_name>/project/</code> and the C source for
-each application is provided in
-<code><ndk>/apps/<app_name>/project/jni/</code>.</p>
+<p>For each sample, the NDK includes the corresponding C source code and the
+necessary Android.mk and Application.mk files. There are located under
+<code><ndk>/samples/<name>/</code> and their source code can be found under
+<code><ndk>/samples/<name>/jni/</code>. </p>
-<p>Once you have installed the NDK and run <code>$ build/host-setup.sh</code> from
-the root of the NDK directory, you can build the shared libraries for the
-sample apps by using these commands:</p>
-<ul>
-<li><code>$ make APP=hello-jni</code> — compiles
-<code>hello-jni.c</code> and outputs a shared library to
-<code><ndk>/apps/hello-jni/project/libs/armeabi/libhello-jni.so</code>.
-</li>
-<li><code>$ make APP=two-libs</code> — compiles
-<code>first.c</code> and <code>second.c</code> and outputs a shared library to
-<code><ndk>/apps/two-libs/project/libs/armeabi/libtwolib-second.so</code>.
-</li>
-<li><code>$ make APP=san-angeles</code> — compiles
-<code>importgl.c</code>, <code>demo.c</code>,and <code>app-android.c</code> and
-outputs a shared library to <code><ndk>/apps/san-angeles/project/libs/armeabi/libsangeles.so</code>.
-</li>
-<li><code>$ make APP=hello-gl2</code> — compiles
-<code>gl_code.cpp</code> and outputs a shared library to
-<code><ndk>/apps/hello-gl2/project/libs/armeabi/libgl2jni.so</code>.
-</li>
-</ul>
+<p>You can build the shared libraries for the sample apps by going into <code><ndk>/samples/<name>/</code>
+then calling the <code>ndk-build</code> command. The generated shared libraries will be located under
+<code><ndk>/samples/<name>/libs/armeabi/</code> for (ARMv5TE machine code) and/or
+<code><ndk>/samples/<name>/libs/armeabi-v7a/</code> for (ARMv7 machine code).
+</p>
<p>Next, build the sample Android applications that use the shared
libraries:</p>
@@ -475,3 +553,4 @@
mailing list.</p>
+
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index a845e55..7438707 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -61,28 +61,21 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1
- Platform</a> <span class="new">new!</span>
- </li>
- <li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6
- Platform</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.5.html">Android 1.5 Platform</a></li>
<li class="toggle-list">
<div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1
- Platform</a>
- </li>
- <li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0
- Platform</a>
- </li>
- <li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a>
- </li>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li>
</ul>
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r5</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r6</a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for
Windows, r3</a>
</li>
@@ -100,8 +93,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT
- <?cs var:adt.zip.version ?></a> <span class="new">new!</span>
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 0.9.7
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
@@ -109,6 +101,7 @@
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span></a>
+ <span class="new">new!</span>
</li>
</ul>
</li>
@@ -123,7 +116,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r3</a>
+ <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4</a>
<span class="new">new!</span></li>
</ul>
</li>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index c60782f..c9be6ff 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -50,6 +50,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
@@ -57,9 +60,41 @@
margin:0;
}
</style>
+
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 6</a> <em>(May 2010)</em>
+ <div class="toggleme">
+
+<dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that SDK Tools r6 is
+designed for use with ADT 0.9.7 and later. After installing SDK Tools r6, we
+highly recommend updating your ADT Plugin to 0.9.7.</p>
+</dd>
+
+<dt>Library projects:</dt>
+<dd>
+<p>The SDK Tools now support the use of <em>library projects</em> during
+development, a capability that lets you store shared Android application
+code and resources in a separate development project. You can then reference the
+library project from other Android projects and, at build time, the tools
+compile the shared code and resources as part of the dependent applications.
+More information about this feature is available in the <a
+href="{@docRoot}guide/developing/other-ide.html#libraryProject">Developing
+in Other IDEs</a> document.</p>
+<p>If you are developing in Eclipse, <a href="eclipse-adt.html">ADT 0.9.7</a>
+provides the equivalent library project support.</p>
+</dd>
+</dl>
+ </div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 5</a> <em>(March 2010)</em>
<div class="toggleme">
diff --git a/docs/html/sdk/win-usb.jd b/docs/html/sdk/win-usb.jd
index 38b34ed..37d2cbb 100644
--- a/docs/html/sdk/win-usb.jd
+++ b/docs/html/sdk/win-usb.jd
@@ -69,6 +69,9 @@
.toggleable a {
text-decoration:none;
}
+.toggleme a {
+ text-decoration:underline;
+}
.toggleable.closed .toggleme {
display:none;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 345f810..064fab6 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -16,11 +16,10 @@
package android.graphics;
-import android.text.TextUtils;
-import android.text.SpannedString;
-import android.text.SpannableString;
import android.text.GraphicsOperations;
-import android.util.DisplayMetrics;
+import android.text.SpannableString;
+import android.text.SpannedString;
+import android.text.TextUtils;
import javax.microedition.khronos.opengles.GL;
@@ -59,6 +58,18 @@
private int mSurfaceFormat;
/**
+ * Flag for drawTextRun indicating left-to-right run direction.
+ * @hide
+ */
+ public static final int DIRECTION_LTR = 0;
+
+ /**
+ * Flag for drawTextRun indicating right-to-left run direction.
+ * @hide
+ */
+ public static final int DIRECTION_RTL = 1;
+
+ /**
* Construct an empty raster canvas. Use setBitmap() to specify a bitmap to
* draw into. The initial target density is {@link Bitmap#DENSITY_NONE};
* this will typically be replaced when a target bitmap is set for the
@@ -1246,8 +1257,8 @@
(text.length - index - count)) < 0) {
throw new IndexOutOfBoundsException();
}
- native_drawText(mNativeCanvas, text, index, count, x, y,
- paint.mNativePaint);
+ native_drawText(mNativeCanvas, text, index, count, x, y, paint.mBidiFlags,
+ paint.mNativePaint);
}
/**
@@ -1259,7 +1270,10 @@
* @param y The y-coordinate of the origin of the text being drawn
* @param paint The paint used for the text (e.g. color, size, style)
*/
- public native void drawText(String text, float x, float y, Paint paint);
+ public void drawText(String text, float x, float y, Paint paint) {
+ native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags,
+ paint.mNativePaint);
+ }
/**
* Draw the text, with origin at (x,y), using the specified paint.
@@ -1277,8 +1291,8 @@
if ((start | end | (end - start) | (text.length() - end)) < 0) {
throw new IndexOutOfBoundsException();
}
- native_drawText(mNativeCanvas, text, start, end, x, y,
- paint.mNativePaint);
+ native_drawText(mNativeCanvas, text, start, end, x, y, paint.mBidiFlags,
+ paint.mNativePaint);
}
/**
@@ -1299,16 +1313,100 @@
if (text instanceof String || text instanceof SpannedString ||
text instanceof SpannableString) {
native_drawText(mNativeCanvas, text.toString(), start, end, x, y,
- paint.mNativePaint);
- }
- else if (text instanceof GraphicsOperations) {
+ paint.mBidiFlags, paint.mNativePaint);
+ } else if (text instanceof GraphicsOperations) {
((GraphicsOperations) text).drawText(this, start, end, x, y,
paint);
- }
- else {
+ } else {
char[] buf = TemporaryBuffer.obtain(end - start);
TextUtils.getChars(text, start, end, buf, 0);
- drawText(buf, 0, end - start, x, y, paint);
+ native_drawText(mNativeCanvas, buf, 0, end - start, x, y,
+ paint.mBidiFlags, paint.mNativePaint);
+ TemporaryBuffer.recycle(buf);
+ }
+ }
+
+ /**
+ * Render a run of all LTR or all RTL text, with shaping. This does not run
+ * bidi on the provided text, but renders it as a uniform right-to-left or
+ * left-to-right run, as indicated by dir. Alignment of the text is as
+ * determined by the Paint's TextAlign value.
+ *
+ * @param text the text to render
+ * @param index the start of the text to render. Data before this position
+ * can be used for shaping context.
+ * @param length the length of the text to render. Data at or after this
+ * position (start + length) can be used for shaping context.
+ * @param x the x position at which to draw the text
+ * @param y the y position at which to draw the text
+ * @param dir the run direction, either {@link DIRECTION_LTR} or
+ * {@link DIRECTION_RTL}.
+ * @param paint the paint
+ * @hide
+ */
+ public void drawTextRun(char[] text, int index, int length, float x, float y, int dir,
+ Paint paint) {
+
+ if (text == null) {
+ throw new NullPointerException("text is null");
+ }
+ if (paint == null) {
+ throw new NullPointerException("paint is null");
+ }
+ if ((index | length | text.length - index - length) < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (dir != DIRECTION_LTR && dir != DIRECTION_RTL) {
+ throw new IllegalArgumentException("unknown dir: " + dir);
+ }
+
+ native_drawTextRun(mNativeCanvas, text, index, length, x, y, dir, paint.mNativePaint);
+ }
+
+ /**
+ * Render a run of all LTR or all RTL text, with shaping. This does not run
+ * bidi on the provided text, but renders it as a uniform right-to-left or
+ * left-to-right run, as indicated by dir. Alignment of the text is as
+ * determined by the Paint's TextAlign value.
+ *
+ * @param text the text to render
+ * @param start the start of the text to render. Data before this position
+ * can be used for shaping context.
+ * @param end the end of the text to render. Data at or after this
+ * position can be used for shaping context.
+ * @param x the x position at which to draw the text
+ * @param y the y position at which to draw the text
+ * @param dir the run direction, either 0 for LTR or 1 for RTL.
+ * @param paint the paint
+ * @hide
+ */
+ public void drawTextRun(CharSequence text, int start, int end, float x,
+ float y, int dir, Paint paint) {
+
+ if (text == null) {
+ throw new NullPointerException("text is null");
+ }
+ if (paint == null) {
+ throw new NullPointerException("paint is null");
+ }
+ if ((start | end | end - start | text.length() - end) < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ int flags = dir == 0 ? 0 : 1;
+
+ if (text instanceof String || text instanceof SpannedString ||
+ text instanceof SpannableString) {
+ native_drawTextRun(mNativeCanvas, text.toString(), start, end, x, y,
+ flags, paint.mNativePaint);
+ } else if (text instanceof GraphicsOperations) {
+ ((GraphicsOperations) text).drawTextRun(this, start, end, x, y, flags,
+ paint);
+ } else {
+ char[] buf = TemporaryBuffer.obtain(end - start);
+ TextUtils.getChars(text, start, end, buf, 0);
+ native_drawTextRun(mNativeCanvas, buf, 0, end - start, x, y,
+ flags, paint.mNativePaint);
TemporaryBuffer.recycle(buf);
}
}
@@ -1555,10 +1653,17 @@
private static native void native_drawText(int nativeCanvas, char[] text,
int index, int count, float x,
- float y, int paint);
+ float y, int flags, int paint);
private static native void native_drawText(int nativeCanvas, String text,
int start, int end, float x,
- float y, int paint);
+ float y, int flags, int paint);
+
+ private static native void native_drawTextRun(int nativeCanvas, String
+ text, int start, int end, float x, float y, int flags, int paint);
+
+ private static native void native_drawTextRun(int nativeCanvas, char[]
+ text, int start, int len, float x, float y, int flags, int paint);
+
private static native void native_drawPosText(int nativeCanvas,
char[] text, int index,
int count, float[] pos,
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 183c896..b564929 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -16,10 +16,10 @@
package android.graphics;
-import android.text.TextUtils;
+import android.text.GraphicsOperations;
import android.text.SpannableString;
import android.text.SpannedString;
-import android.text.GraphicsOperations;
+import android.text.TextUtils;
/**
* The Paint class holds the style and color information about how to draw
@@ -39,6 +39,7 @@
private boolean mHasCompatScaling;
private float mCompatScaling;
private float mInvCompatScaling;
+ /* package */ int mBidiFlags = BIDI_DEFAULT_LTR;
private static final Style[] sStyleArray = {
Style.FILL, Style.STROKE, Style.FILL_AND_STROKE
@@ -76,8 +77,64 @@
private static final int DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG;
/**
- * The Style specifies if the primitive being drawn is filled,
- * stroked, or both (in the same color). The default is FILL.
+ * Bidi flag to set LTR paragraph direction.
+ *
+ * @hide
+ */
+ public static final int BIDI_LTR = 0x0;
+
+ /**
+ * Bidi flag to set RTL paragraph direction.
+ *
+ * @hide
+ */
+ public static final int BIDI_RTL = 0x1;
+
+ /**
+ * Bidi flag to detect paragraph direction via heuristics, defaulting to
+ * LTR.
+ *
+ * @hide
+ */
+ public static final int BIDI_DEFAULT_LTR = 0x2;
+
+ /**
+ * Bidi flag to detect paragraph direction via heuristics, defaulting to
+ * RTL.
+ *
+ * @hide
+ */
+ public static final int BIDI_DEFAULT_RTL = 0x3;
+
+ /**
+ * Bidi flag to override direction to all LTR (ignore bidi).
+ *
+ * @hide
+ */
+ public static final int BIDI_FORCE_LTR = 0x4;
+
+ /**
+ * Bidi flag to override direction to all RTL (ignore bidi).
+ *
+ * @hide
+ */
+ public static final int BIDI_FORCE_RTL = 0x5;
+
+ /**
+ * Maximum Bidi flag value.
+ * @hide
+ */
+ private static final int BIDI_MAX_FLAG_VALUE = BIDI_FORCE_RTL;
+
+ /**
+ * Mask for bidi flags.
+ * @hide
+ */
+ private static final int BIDI_FLAG_MASK = 0x7;
+
+ /**
+ * The Style specifies if the primitive being drawn is filled, stroked, or
+ * both (in the same color). The default is FILL.
*/
public enum Style {
/**
@@ -210,6 +267,7 @@
mHasCompatScaling = paint.mHasCompatScaling;
mCompatScaling = paint.mCompatScaling;
mInvCompatScaling = paint.mInvCompatScaling;
+ mBidiFlags = paint.mBidiFlags;
}
/** Restores the paint to its default settings. */
@@ -218,6 +276,7 @@
setFlags(DEFAULT_PAINT_FLAGS);
mHasCompatScaling = false;
mCompatScaling = mInvCompatScaling = 1;
+ mBidiFlags = BIDI_DEFAULT_LTR;
}
/**
@@ -240,6 +299,7 @@
mHasCompatScaling = src.mHasCompatScaling;
mCompatScaling = src.mCompatScaling;
mInvCompatScaling = src.mInvCompatScaling;
+ mBidiFlags = src.mBidiFlags;
}
}
@@ -254,10 +314,33 @@
mInvCompatScaling = 1.0f/factor;
}
}
-
+
+ /**
+ * Return the bidi flags on the paint.
+ *
+ * @return the bidi flags on the paint
+ * @hide
+ */
+ public int getBidiFlags() {
+ return mBidiFlags;
+ }
+
+ /**
+ * Set the bidi flags on the paint.
+ * @hide
+ */
+ public void setBidiFlags(int flags) {
+ // only flag value is the 3-bit BIDI control setting
+ flags &= BIDI_FLAG_MASK;
+ if (flags > BIDI_MAX_FLAG_VALUE) {
+ throw new IllegalArgumentException("unknown bidi flag: " + flags);
+ }
+ mBidiFlags = flags;
+ }
+
/**
* Return the paint's flags. Use the Flag enum to test flag values.
- *
+ *
* @return the paint's flags (see enums ending in _Flag for bit masks)
*/
public native int getFlags();
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 0d27f1a..979df9f 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -39,23 +39,16 @@
int getInt(const char *key) const;
float getFloat(const char *key) const;
- /* preview-size=176x144 */
+ void remove(const char *key);
+
void setPreviewSize(int width, int height);
void getPreviewSize(int *width, int *height) const;
-
- /* preview-fps=15 */
void setPreviewFrameRate(int fps);
int getPreviewFrameRate() const;
-
- /* preview-format=rgb565|yuv422 */
void setPreviewFormat(const char *format);
const char *getPreviewFormat() const;
-
- /* picture-size=1024x768 */
void setPictureSize(int width, int height);
void getPictureSize(int *width, int *height) const;
-
- /* picture-format=yuv422|jpeg */
void setPictureFormat(const char *format);
const char *getPictureFormat() const;
diff --git a/include/media/stagefright/HTTPDataSource.h b/include/media/stagefright/HTTPDataSource.h
index f3b44fd..0400bea 100644
--- a/include/media/stagefright/HTTPDataSource.h
+++ b/include/media/stagefright/HTTPDataSource.h
@@ -91,6 +91,7 @@
void initHeaders(const KeyedVector<String8, String8> *overrides);
status_t connectWithRedirectsAndRange(off_t rangeStart);
+ void applyTimeoutResponse();
HTTPDataSource(const HTTPDataSource &);
HTTPDataSource &operator=(const HTTPDataSource &);
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 2504d39..c23832d 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -129,7 +129,7 @@
// ----------------------------------------------------------------------------
-// 4 KB max
+// 32 KB max
class SharedClient
{
public:
@@ -166,7 +166,7 @@
protected:
SharedClient* const mSharedClient;
SharedBufferStack* const mSharedStack;
- const int mNumBuffers;
+ int mNumBuffers;
const int mIdentity;
int32_t computeTail() const;
@@ -217,6 +217,7 @@
bool needNewBuffer(int buffer) const;
status_t setDirtyRegion(int buffer, const Region& reg);
status_t setCrop(int buffer, const Rect& reg);
+ status_t setBufferCount(int bufferCount);
private:
friend struct Condition;
@@ -269,13 +270,61 @@
status_t reallocate();
status_t assertReallocate(int buffer);
int32_t getQueuedCount() const;
-
Region getDirtyRegion(int buffer) const;
+ status_t resize(int newNumBuffers);
+
SharedBufferStack::Statistics getStats() const;
private:
+ /*
+ * BufferList is basically a fixed-capacity sorted-vector of
+ * unsigned 5-bits ints using a 32-bits int as storage.
+ * it has efficient iterators to find items in the list and not in the list.
+ */
+ class BufferList {
+ size_t mCapacity;
+ uint32_t mList;
+ public:
+ BufferList(size_t c = NUM_BUFFER_MAX) : mCapacity(c), mList(0) { }
+ status_t add(int value);
+ status_t remove(int value);
+
+ class const_iterator {
+ friend class BufferList;
+ uint32_t mask, curr;
+ const_iterator(uint32_t mask) :
+ mask(mask), curr(31 - __builtin_clz(mask)) { }
+ public:
+ inline bool operator == (const const_iterator& rhs) const {
+ return mask == rhs.mask;
+ }
+ inline bool operator != (const const_iterator& rhs) const {
+ return mask != rhs.mask;
+ }
+ inline int operator *() const { return curr; }
+ inline const const_iterator& operator ++(int) {
+ mask &= ~curr;
+ curr = 31 - __builtin_clz(mask);
+ return *this;
+ }
+ };
+
+ inline const_iterator begin() const {
+ return const_iterator(mList);
+ }
+ inline const_iterator end() const {
+ return const_iterator(0);
+ }
+ inline const_iterator free_begin() const {
+ uint32_t mask = (1 << (32-mCapacity)) - 1;
+ return const_iterator( ~(mList | mask) );
+ }
+ };
+
+ BufferList mBufferList;
+
struct UnlockUpdate : public UpdateBase {
const int lockedBuffer;
inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 472f759..9476686 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -47,12 +47,14 @@
POST_BUFFER, // one-way transaction
CREATE_OVERLAY,
REQUEST_BUFFER,
+ SET_BUFFER_COUNT,
};
public:
DECLARE_META_INTERFACE(Surface);
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0;
+ virtual status_t setBufferCount(int bufferCount) = 0;
class BufferHeap {
public:
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 7ab3a00..973780f 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -217,6 +217,7 @@
int connect(int api);
int disconnect(int api);
int crop(Rect const* rect);
+ int setBufferCount(int bufferCount);
/*
* private stuff...
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index 30e0036..e38bf66 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -47,8 +47,8 @@
const char* fileName);
extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
- int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+ int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 51c4f2f..97d31f4 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -58,14 +58,19 @@
class ZipFileRO {
public:
ZipFileRO()
- : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+ : mFd(-1), mFileName(NULL), mFileLength(-1),
+ mDirectoryMap(NULL),
+ mNumEntries(-1), mDirectoryOffset(-1),
+ mHashTableSize(-1), mHashTable(NULL)
{}
~ZipFileRO() {
free(mHashTable);
- if (mFileMap)
- mFileMap->release();
+ if (mDirectoryMap)
+ mDirectoryMap->release();
if (mFd >= 0)
close(mFd);
+ if (mFileName)
+ free(mFileName);
}
/*
@@ -118,8 +123,8 @@
* Returns "false" if "entry" is bogus or if the data in the Zip file
* appears to be bad.
*/
- bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+ bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
/*
* Create a new FileMap object that maps a subset of the archive. For
@@ -155,13 +160,13 @@
* Utility function: uncompress deflated data, buffer to buffer.
*/
static bool inflateBuffer(void* outBuf, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Utility function: uncompress deflated data, buffer to fd.
*/
static bool inflateBuffer(int fd, const void* inBuf,
- long uncompLen, long compLen);
+ size_t uncompLen, size_t compLen);
/*
* Some basic functions for raw data manipulation. "LE" means
@@ -179,6 +184,9 @@
ZipFileRO(const ZipFileRO& src);
ZipFileRO& operator=(const ZipFileRO& src);
+ /* locate and parse the central directory */
+ bool mapCentralDirectory(void);
+
/* parse the archive, prepping internal structures */
bool parseZipArchive(void);
@@ -203,12 +211,21 @@
/* open Zip archive */
int mFd;
+ /* zip file name */
+ char* mFileName;
+
+ /* length of file */
+ size_t mFileLength;
+
/* mapped file */
- FileMap* mFileMap;
+ FileMap* mDirectoryMap;
/* number of entries in the Zip archive */
int mNumEntries;
+ /* CD directory offset in the Zip archive */
+ off_t mDirectoryOffset;
+
/*
* We know how many entries are in the Zip archive, so we have a
* fixed-size hash table. We probe for an empty slot.
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
index a018b4c..6c11114 100644
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ b/libs/audioflinger/AudioDumpInterface.cpp
@@ -32,7 +32,7 @@
// ----------------------------------------------------------------------------
AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
- : mFirstHwOutput(true), mPolicyCommands(String8("")), mFileName(String8(""))
+ : mPolicyCommands(String8("")), mFileName(String8(""))
{
if(hw == 0) {
LOGE("Dump construct hw = 0");
@@ -47,6 +47,11 @@
for (size_t i = 0; i < mOutputs.size(); i++) {
closeOutputStream((AudioStreamOut *)mOutputs[i]);
}
+
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ closeInputStream((AudioStreamIn *)mInputs[i]);
+ }
+
if(mFinalInterface) delete mFinalInterface;
}
@@ -60,31 +65,32 @@
uint32_t lRate = 44100;
- if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices) || mFirstHwOutput) {
- outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
- if (outFinal != 0) {
- lFormat = outFinal->format();
- lChannels = outFinal->channels();
- lRate = outFinal->sampleRate();
- if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
- mFirstHwOutput = false;
+ outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
+ if (outFinal != 0) {
+ lFormat = outFinal->format();
+ lChannels = outFinal->channels();
+ lRate = outFinal->sampleRate();
+ } else {
+ if (format != 0) {
+ if (*format != 0) {
+ lFormat = *format;
+ } else {
+ *format = lFormat;
}
}
- } else {
- if (format != 0 && *format != 0) {
- lFormat = *format;
- } else {
- lFormat = AudioSystem::PCM_16_BIT;
+ if (channels != 0) {
+ if (*channels != 0) {
+ lChannels = *channels;
+ } else {
+ *channels = lChannels;
+ }
}
- if (channels != 0 && *channels != 0) {
- lChannels = *channels;
- } else {
- lChannels = AudioSystem::CHANNEL_OUT_STEREO;
- }
- if (sampleRate != 0 && *sampleRate != 0) {
- lRate = *sampleRate;
- } else {
- lRate = 44100;
+ if (sampleRate != 0) {
+ if (*sampleRate != 0) {
+ lRate = *sampleRate;
+ } else {
+ *sampleRate = lRate;
+ }
}
if (status) *status = NO_ERROR;
}
@@ -111,7 +117,6 @@
dumpOut->standby();
if (dumpOut->finalStream() != NULL) {
mFinalInterface->closeOutputStream(dumpOut->finalStream());
- mFirstHwOutput = true;
}
mOutputs.remove(dumpOut);
@@ -126,18 +131,33 @@
uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
uint32_t lRate = 8000;
-
- if (mInputs.size() == 0) {
- inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
- if (inFinal == 0) return 0;
-
+ inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
+ if (inFinal != 0) {
lFormat = inFinal->format();
lChannels = inFinal->channels();
lRate = inFinal->sampleRate();
} else {
- if (format != 0 && *format != 0) lFormat = *format;
- if (channels != 0 && *channels != 0) lChannels = *channels;
- if (sampleRate != 0 && *sampleRate != 0) lRate = *sampleRate;
+ if (format != 0) {
+ if (*format != 0) {
+ lFormat = *format;
+ } else {
+ *format = lFormat;
+ }
+ }
+ if (channels != 0) {
+ if (*channels != 0) {
+ lChannels = *channels;
+ } else {
+ *channels = lChannels;
+ }
+ }
+ if (sampleRate != 0) {
+ if (*sampleRate != 0) {
+ lRate = *sampleRate;
+ } else {
+ *sampleRate = lRate;
+ }
+ }
if (status) *status = NO_ERROR;
}
LOGV("openInputStream(), inFinal %p", inFinal);
@@ -223,6 +243,15 @@
return keyValuePairs;
}
+status_t AudioDumpInterface::setMode(int mode)
+{
+ return mFinalInterface->setMode(mode);
+}
+
+size_t AudioDumpInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+ return mFinalInterface->getInputBufferSize(sampleRate, format, channelCount);
+}
// ----------------------------------------------------------------------------
@@ -235,7 +264,7 @@
uint32_t sampleRate)
: mInterface(interface), mId(id),
mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
- mBufferSize(1024), mFinalStream(finalStream), mOutFile(0), mFileCount(0)
+ mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
{
LOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
}
@@ -254,26 +283,26 @@
if (mFinalStream) {
ret = mFinalStream->write(buffer, bytes);
} else {
- usleep((bytes * 1000000) / frameSize() / sampleRate());
+ usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
ret = bytes;
}
- if(!mOutFile) {
+ if(!mFile) {
if (mInterface->fileName() != "") {
char name[255];
- sprintf(name, "%s_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
- mOutFile = fopen(name, "wb");
- LOGV("Opening dump file %s, fh %p", name, mOutFile);
+ sprintf(name, "%s_out_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
+ mFile = fopen(name, "wb");
+ LOGV("Opening dump file %s, fh %p", name, mFile);
}
}
- if (mOutFile) {
- fwrite(buffer, bytes, 1, mOutFile);
+ if (mFile) {
+ fwrite(buffer, bytes, 1, mFile);
}
return ret;
}
status_t AudioStreamOutDump::standby()
{
- LOGV("AudioStreamOutDump standby(), mOutFile %p, mFinalStream %p", mOutFile, mFinalStream);
+ LOGV("AudioStreamOutDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
Close();
if (mFinalStream != 0 ) return mFinalStream->standby();
@@ -330,7 +359,7 @@
}
if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
- if (mOutFile == 0) {
+ if (mFile == 0) {
mFormat = valueInt;
} else {
status = INVALID_OPERATION;
@@ -345,7 +374,7 @@
}
if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
if (valueInt > 0 && valueInt <= 48000) {
- if (mOutFile == 0) {
+ if (mFile == 0) {
mSampleRate = valueInt;
} else {
status = INVALID_OPERATION;
@@ -373,9 +402,9 @@
void AudioStreamOutDump::Close()
{
- if(mOutFile) {
- fclose(mOutFile);
- mOutFile = 0;
+ if(mFile) {
+ fclose(mFile);
+ mFile = 0;
}
}
@@ -396,7 +425,7 @@
uint32_t sampleRate)
: mInterface(interface), mId(id),
mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
- mBufferSize(1024), mFinalStream(finalStream), mInFile(0)
+ mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
{
LOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
}
@@ -409,55 +438,68 @@
ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
{
+ ssize_t ret;
+
if (mFinalStream) {
- return mFinalStream->read(buffer, bytes);
- }
-
- usleep((bytes * 1000000) / frameSize() / sampleRate());
-
- if(!mInFile) {
- char name[255];
- strcpy(name, "/sdcard/music/sine440");
- if (channels() == AudioSystem::CHANNEL_IN_MONO) {
- strcat(name, "_mo");
- } else {
- strcat(name, "_st");
+ ret = mFinalStream->read(buffer, bytes);
+ if(!mFile) {
+ if (mInterface->fileName() != "") {
+ char name[255];
+ sprintf(name, "%s_in_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
+ mFile = fopen(name, "wb");
+ LOGV("Opening input dump file %s, fh %p", name, mFile);
+ }
}
- if (format() == AudioSystem::PCM_16_BIT) {
- strcat(name, "_16b");
- } else {
- strcat(name, "_8b");
+ if (mFile) {
+ fwrite(buffer, bytes, 1, mFile);
}
- if (sampleRate() < 16000) {
- strcat(name, "_8k");
- } else if (sampleRate() < 32000) {
- strcat(name, "_22k");
- } else if (sampleRate() < 48000) {
- strcat(name, "_44k");
- } else {
- strcat(name, "_48k");
+ } else {
+ usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
+ ret = bytes;
+ if(!mFile) {
+ char name[255];
+ strcpy(name, "/sdcard/music/sine440");
+ if (channels() == AudioSystem::CHANNEL_IN_MONO) {
+ strcat(name, "_mo");
+ } else {
+ strcat(name, "_st");
+ }
+ if (format() == AudioSystem::PCM_16_BIT) {
+ strcat(name, "_16b");
+ } else {
+ strcat(name, "_8b");
+ }
+ if (sampleRate() < 16000) {
+ strcat(name, "_8k");
+ } else if (sampleRate() < 32000) {
+ strcat(name, "_22k");
+ } else if (sampleRate() < 48000) {
+ strcat(name, "_44k");
+ } else {
+ strcat(name, "_48k");
+ }
+ strcat(name, ".wav");
+ mFile = fopen(name, "rb");
+ LOGV("Opening input read file %s, fh %p", name, mFile);
+ if (mFile) {
+ fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
+ }
}
- strcat(name, ".wav");
- mInFile = fopen(name, "rb");
- LOGV("Opening dump file %s, fh %p", name, mInFile);
- if (mInFile) {
- fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
- }
-
- }
- if (mInFile) {
- ssize_t bytesRead = fread(buffer, bytes, 1, mInFile);
- if (bytesRead != bytes) {
- fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
- fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mInFile);
+ if (mFile) {
+ ssize_t bytesRead = fread(buffer, bytes, 1, mFile);
+ if (bytesRead >=0 && bytesRead < bytes) {
+ fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
+ fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mFile);
+ }
}
}
- return bytes;
+
+ return ret;
}
status_t AudioStreamInDump::standby()
{
- LOGV("AudioStreamInDump standby(), mInFile %p, mFinalStream %p", mInFile, mFinalStream);
+ LOGV("AudioStreamInDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
Close();
if (mFinalStream != 0 ) return mFinalStream->standby();
@@ -523,9 +565,9 @@
void AudioStreamInDump::Close()
{
- if(mInFile) {
- fclose(mInFile);
- mInFile = 0;
+ if(mFile) {
+ fclose(mFile);
+ mFile = 0;
}
}
}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 4c62b3e..814ce5f 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -69,7 +69,7 @@
uint32_t mDevice; // current device this output is routed to
size_t mBufferSize;
AudioStreamOut *mFinalStream;
- FILE *mOutFile; // output file
+ FILE *mFile; // output file
int mFileCount;
};
@@ -109,7 +109,8 @@
uint32_t mDevice; // current device this output is routed to
size_t mBufferSize;
AudioStreamIn *mFinalStream;
- FILE *mInFile; // output file
+ FILE *mFile; // output file
+ int mFileCount;
};
class AudioDumpInterface : public AudioHardwareBase
@@ -134,6 +135,8 @@
virtual status_t setMasterVolume(float volume)
{return mFinalInterface->setMasterVolume(volume);}
+ virtual status_t setMode(int mode);
+
// mic mute
virtual status_t setMicMute(bool state)
{return mFinalInterface->setMicMute(state);}
@@ -143,6 +146,8 @@
virtual status_t setParameters(const String8& keyValuePairs);
virtual String8 getParameters(const String8& keys);
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+
virtual AudioStreamIn* openInputStream(uint32_t devices, int *format, uint32_t *channels,
uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics);
virtual void closeInputStream(AudioStreamIn* in);
@@ -153,8 +158,7 @@
protected:
AudioHardwareInterface *mFinalInterface;
- SortedVector<AudioStreamOutDump *> mOutputs;
- bool mFirstHwOutput;
+ SortedVector<AudioStreamOutDump *> mOutputs;
SortedVector<AudioStreamInDump *> mInputs;
Mutex mLock;
String8 mPolicyCommands;
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 2414e8d..06443ef 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -142,6 +142,7 @@
}
#ifdef LVMX
LifeVibes::init();
+ mLifeVibesClientPid = -1;
#endif
}
@@ -596,8 +597,10 @@
int musicEnabled = -1;
if (NO_ERROR == param.get(key, value)) {
if (value == LifevibesEnable) {
+ mLifeVibesClientPid = IPCThreadState::self()->getCallingPid();
musicEnabled = 1;
} else if (value == LifevibesDisable) {
+ mLifeVibesClientPid = -1;
musicEnabled = 0;
}
}
@@ -609,7 +612,7 @@
mHardwareStatus = AUDIO_SET_PARAMETER;
result = mAudioHardware->setParameters(keyValuePairs);
#ifdef LVMX
- if ((NO_ERROR == result) && (musicEnabled != -1)) {
+ if (musicEnabled != -1) {
LifeVibes::enableMusic((bool) musicEnabled);
}
#endif
@@ -713,51 +716,57 @@
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
{
- LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
Mutex::Autolock _l(mLock);
- sp<IBinder> binder = client->asBinder();
- if (mNotificationClients.indexOf(binder) < 0) {
- LOGV("Adding notification client %p", binder.get());
- binder->linkToDeath(this);
- mNotificationClients.add(binder);
- }
+ int pid = IPCThreadState::self()->getCallingPid();
+ if (mNotificationClients.indexOfKey(pid) < 0) {
+ sp<NotificationClient> notificationClient = new NotificationClient(this,
+ client,
+ pid);
+ LOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
- // the config change is always sent from playback or record threads to avoid deadlock
- // with AudioSystem::gLock
- for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- mPlaybackThreads.valueAt(i)->sendConfigEvent(AudioSystem::OUTPUT_OPENED);
- }
+ mNotificationClients.add(pid, notificationClient);
- for (size_t i = 0; i < mRecordThreads.size(); i++) {
- mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
- }
-}
+ sp<IBinder> binder = client->asBinder();
+ binder->linkToDeath(notificationClient);
-void AudioFlinger::binderDied(const wp<IBinder>& who) {
+ // the config change is always sent from playback or record threads to avoid deadlock
+ // with AudioSystem::gLock
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ mPlaybackThreads.valueAt(i)->sendConfigEvent(AudioSystem::OUTPUT_OPENED);
+ }
- LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
-
- IBinder *binder = who.unsafe_get();
-
- if (binder != NULL) {
- int index = mNotificationClients.indexOf(binder);
- if (index >= 0) {
- LOGV("Removing notification client %p", binder);
- mNotificationClients.removeAt(index);
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
}
}
}
+void AudioFlinger::removeNotificationClient(pid_t pid)
+{
+ Mutex::Autolock _l(mLock);
+
+ int index = mNotificationClients.indexOfKey(pid);
+ if (index >= 0) {
+ sp <NotificationClient> client = mNotificationClients.valueFor(pid);
+ LOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
+#ifdef LVMX
+ if (pid == mLifeVibesClientPid) {
+ LOGV("Disabling lifevibes");
+ LifeVibes::enableMusic(false);
+ mLifeVibesClientPid = -1;
+ }
+#endif
+ mNotificationClients.removeItem(pid);
+ }
+}
+
// audioConfigChanged_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) {
+void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2)
+{
size_t size = mNotificationClients.size();
for (size_t i = 0; i < size; i++) {
- sp<IBinder> binder = mNotificationClients.itemAt(i);
- LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
- sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
- client->ioConfigChanged(event, ioHandle, param2);
+ mNotificationClients.valueAt(i)->client()->ioConfigChanged(event, ioHandle, param2);
}
}
@@ -768,6 +777,7 @@
mClients.removeItem(pid);
}
+
// ----------------------------------------------------------------------------
AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
@@ -3086,6 +3096,28 @@
// ----------------------------------------------------------------------------
+AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
+ const sp<IAudioFlingerClient>& client,
+ pid_t pid)
+ : mAudioFlinger(audioFlinger), mPid(pid), mClient(client)
+{
+}
+
+AudioFlinger::NotificationClient::~NotificationClient()
+{
+ mClient.clear();
+}
+
+void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
+{
+ sp<NotificationClient> keep(this);
+ {
+ mAudioFlinger->removeNotificationClient(mPid);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
: BnAudioTrack(),
mTrack(track)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 739ec33..13aac8b 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -57,7 +57,7 @@
static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
+class AudioFlinger : public BnAudioFlinger
{
public:
static void instantiate();
@@ -139,9 +139,6 @@
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);
- // IBinder::DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
-
enum hardware_call_state {
AUDIO_HW_IDLE = 0,
AUDIO_HW_INIT,
@@ -205,6 +202,27 @@
pid_t mPid;
};
+ // --- Notification Client ---
+ class NotificationClient : public IBinder::DeathRecipient {
+ public:
+ NotificationClient(const sp<AudioFlinger>& audioFlinger,
+ const sp<IAudioFlingerClient>& client,
+ pid_t pid);
+ virtual ~NotificationClient();
+
+ sp<IAudioFlingerClient> client() { return mClient; }
+
+ // IBinder::DeathRecipient
+ virtual void binderDied(const wp<IBinder>& who);
+
+ private:
+ NotificationClient(const NotificationClient&);
+ NotificationClient& operator = (const NotificationClient&);
+
+ sp<AudioFlinger> mAudioFlinger;
+ pid_t mPid;
+ sp<IAudioFlingerClient> mClient;
+ };
class TrackHandle;
class RecordHandle;
@@ -685,6 +703,7 @@
void removeClient_l(pid_t pid);
+ void removeNotificationClient(pid_t pid);
// record thread
@@ -796,8 +815,11 @@
DefaultKeyedVector< int, sp<RecordThread> > mRecordThreads;
- SortedVector< sp<IBinder> > mNotificationClients;
+ DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
int mNextThreadId;
+#ifdef LVMX
+ int mLifeVibesClientPid;
+#endif
};
// ----------------------------------------------------------------------------
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index d8f9c71..cfb7ba1 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -254,6 +254,11 @@
return strtof(v, 0);
}
+void CameraParameters::remove(const char *key)
+{
+ mMap.removeItem(String8(key));
+}
+
static int parse_size(const char *str, int &width, int &height)
{
// Find the width.
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 86eb78d..b8a0630 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -13,6 +13,7 @@
LayerDim.cpp \
MessageQueue.cpp \
SurfaceFlinger.cpp \
+ TextureManager.cpp \
Tokenizer.cpp \
Transform.cpp
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index d979f00..af89e9a 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -125,7 +125,6 @@
EGLint numConfigs=0;
EGLSurface surface;
EGLContext context;
- mFlags = CACHED_BUFFERS;
// TODO: all the extensions below should be queried through
// eglGetProcAddress().
@@ -253,15 +252,6 @@
LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);
-#if 0
- // for drivers that don't have proper support for flushing cached buffers
- // on gralloc unlock, uncomment this block and test for the specific
- // renderer substring
- if (strstr(gl_renderer, "<some vendor string>")) {
- LOGD("Assuming uncached graphics buffers.");
- mFlags &= ~CACHED_BUFFERS;
- }
-#endif
if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
mFlags |= NPOT_EXTENSION;
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 897a6ed..ebd7c42 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -50,7 +50,6 @@
PARTIAL_UPDATES = 0x00020000, // video driver feature
SLOW_CONFIG = 0x00040000, // software
SWAP_RECTANGLE = 0x00080000,
- CACHED_BUFFERS = 0x00100000
};
DisplayHardware(
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index e6658fa7..1fe997d 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -48,41 +48,48 @@
// ---------------------------------------------------------------------------
Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
- const sp<Client>& c, int32_t i)
- : LayerBaseClient(flinger, display, c, i),
+ const sp<Client>& client, int32_t i)
+ : LayerBaseClient(flinger, display, client, i),
+ lcblk(NULL),
mSecure(false),
- mNoEGLImageForSwBuffers(false),
mNeedsBlending(true),
- mNeedsDithering(false)
+ mNeedsDithering(false),
+ mTextureManager(mFlags),
+ mBufferManager(mTextureManager)
{
// no OpenGL operation is possible here, since we might not be
// in the OpenGL thread.
- mFrontBufferIndex = lcblk->getFrontBuffer();
+ lcblk = new SharedBufferServer(
+ client->ctrlblk, i, mBufferManager.getBufferCount(),
+ getIdentity());
+
+ mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() );
}
Layer::~Layer()
{
destroy();
// the actual buffers will be destroyed here
+ delete lcblk;
+}
+
+// called with SurfaceFlinger::mStateLock as soon as the layer is entered
+// in the purgatory list
+void Layer::onRemoved()
+{
+ // wake up the condition
+ lcblk->setStatus(NO_INIT);
}
void Layer::destroy()
{
- for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
- if (mTextures[i].name != -1U) {
- glDeleteTextures(1, &mTextures[i].name);
- mTextures[i].name = -1U;
- }
- if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
- EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
- eglDestroyImageKHR(dpy, mTextures[i].image);
- mTextures[i].image = EGL_NO_IMAGE_KHR;
- }
- Mutex::Autolock _l(mLock);
- mBuffers[i].clear();
- mWidth = mHeight = 0;
- }
+ EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+ mBufferManager.destroy(dpy);
+
mSurface.clear();
+
+ Mutex::Autolock _l(mLock);
+ mWidth = mHeight = 0;
}
sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -126,24 +133,19 @@
mHeight = h;
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
- mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
// we use the red index
int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
mNeedsDithering = layerRedsize > displayRedSize;
- for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
- mBuffers[i] = new GraphicBuffer();
- }
mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
return NO_ERROR;
}
void Layer::reloadTexture(const Region& dirty)
{
- Mutex::Autolock _l(mLock);
- sp<GraphicBuffer> buffer(getFrontBufferLocked());
+ sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
if (buffer == NULL) {
// this situation can happen if we ran out of memory for instance.
// not much we can do. continue to use whatever texture was bound
@@ -151,118 +153,24 @@
return;
}
- const int index = mFrontBufferIndex;
-
- // create the new texture name if needed
- if (UNLIKELY(mTextures[index].name == -1U)) {
- mTextures[index].name = createTexture();
- mTextures[index].width = 0;
- mTextures[index].height = 0;
- }
-
#ifdef EGL_ANDROID_image_native_buffer
if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
- if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
- if (mTextures[index].dirty) {
- if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) {
- // not sure what we can do here...
- mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
- goto slowpath;
- }
- }
- } else {
- if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
- mHybridBuffer->height != buffer->height)) {
- mHybridBuffer.clear();
- mHybridBuffer = new GraphicBuffer(
- buffer->width, buffer->height, buffer->format,
- GraphicBuffer::USAGE_SW_WRITE_OFTEN |
- GraphicBuffer::USAGE_HW_TEXTURE);
- if (initializeEglImage(
- mHybridBuffer, &mTextures[0]) != NO_ERROR) {
- // not sure what we can do here...
- mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
- mHybridBuffer.clear();
- goto slowpath;
- }
- }
-
- GGLSurface t;
- status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
- LOGE_IF(res, "error %d (%s) locking buffer %p",
- res, strerror(res), buffer.get());
- if (res == NO_ERROR) {
- Texture* const texture(&mTextures[0]);
-
- glBindTexture(GL_TEXTURE_2D, texture->name);
-
- sp<GraphicBuffer> buf(mHybridBuffer);
- void* vaddr;
- res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr);
- if (res == NO_ERROR) {
- int bpp = 0;
- switch (t.format) {
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- bpp = 2;
- break;
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- bpp = 4;
- break;
- default:
- if (isSupportedYuvFormat(t.format)) {
- // just show the Y plane of YUV buffers
- bpp = 1;
- break;
- }
- // oops, we don't handle this format!
- LOGE("layer %p, texture=%d, using format %d, which is not "
- "supported by the GL", this, texture->name, t.format);
- }
- if (bpp) {
- const Rect bounds(dirty.getBounds());
- size_t src_stride = t.stride;
- size_t dst_stride = buf->stride;
- if (src_stride == dst_stride &&
- bounds.width() == t.width &&
- bounds.height() == t.height)
- {
- memcpy(vaddr, t.data, t.height * t.stride * bpp);
- } else {
- GLubyte const * src = t.data +
- (bounds.left + bounds.top * src_stride) * bpp;
- GLubyte * dst = (GLubyte *)vaddr +
- (bounds.left + bounds.top * dst_stride) * bpp;
- const size_t length = bounds.width() * bpp;
- size_t h = bounds.height();
- src_stride *= bpp;
- dst_stride *= bpp;
- while (h--) {
- memcpy(dst, src, length);
- dst += dst_stride;
- src += src_stride;
- }
- }
- }
- buf->unlock();
- }
- buffer->unlock();
- }
+ EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+ if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
+ // not sure what we can do here...
+ mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+ goto slowpath;
}
} else
#endif
{
slowpath:
- for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
- mTextures[i].image = EGL_NO_IMAGE_KHR;
- }
GGLSurface t;
status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
LOGE_IF(res, "error %d (%s) locking buffer %p",
res, strerror(res), buffer.get());
if (res == NO_ERROR) {
- loadTexture(&mTextures[0], dirty, t);
+ mBufferManager.loadTexture(dirty, t);
buffer->unlock();
}
}
@@ -270,11 +178,8 @@
void Layer::onDraw(const Region& clip) const
{
- int index = mFrontBufferIndex;
- if (mTextures[index].image == EGL_NO_IMAGE_KHR)
- index = 0;
- GLuint textureName = mTextures[index].name;
- if (UNLIKELY(textureName == -1LU)) {
+ Texture tex(mBufferManager.getActiveTexture());
+ if (tex.name == -1LU) {
// the texture has not been created yet, this Layer has
// in fact never been drawn into. This happens frequently with
// SurfaceView because the WindowManager can't know when the client
@@ -300,7 +205,31 @@
}
return;
}
- drawWithOpenGL(clip, mTextures[index]);
+ drawWithOpenGL(clip, tex);
+}
+
+
+status_t Layer::setBufferCount(int bufferCount)
+{
+ // this ensures our client doesn't go away while we're accessing
+ // the shared area.
+ sp<Client> ourClient(client.promote());
+ if (ourClient == 0) {
+ // oops, the client is already gone
+ return DEAD_OBJECT;
+ }
+
+ status_t err;
+
+ // FIXME: resize() below is NOT thread-safe, we need to synchronize
+ // the users of lcblk in our process (ie: retire), and we assume the
+ // client is not mucking with the SharedStack, which is only enforced
+ // by construction, therefore we need to protect ourselves against
+ // buggy and malicious client (as always)
+
+ err = lcblk->resize(bufferCount);
+
+ return err;
}
sp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
@@ -337,15 +266,7 @@
Mutex::Autolock _l(mLock);
w = mWidth;
h = mHeight;
- buffer = mBuffers[index];
-
- // destroy() could have been called before we get here, we log it
- // because it's uncommon, and the code below should handle it
- LOGW_IF(buffer==0,
- "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
- index, w, h);
-
- mBuffers[index].clear();
+ buffer = mBufferManager.detachBuffer(index);
}
const uint32_t effectiveUsage = getEffectiveUsage(usage);
@@ -373,10 +294,7 @@
if (err == NO_ERROR && buffer->handle != 0) {
Mutex::Autolock _l(mLock);
if (mWidth && mHeight) {
- // and we have new buffer
- mBuffers[index] = buffer;
- // texture is now dirty...
- mTextures[index].dirty = true;
+ mBufferManager.attachBuffer(index, buffer);
} else {
// oops we got killed while we were allocating the buffer
buffer.clear();
@@ -406,15 +324,8 @@
} else {
// it's allowed to modify the usage flags here, but generally
// the requested flags should be honored.
- if (mNoEGLImageForSwBuffers) {
- if (usage & GraphicBuffer::USAGE_HW_MASK) {
- // request EGLImage for h/w buffers only
- usage |= GraphicBuffer::USAGE_HW_TEXTURE;
- }
- } else {
- // request EGLImage for all buffers
- usage |= GraphicBuffer::USAGE_HW_TEXTURE;
- }
+ // request EGLImage for all buffers
+ usage |= GraphicBuffer::USAGE_HW_TEXTURE;
}
return usage;
}
@@ -428,13 +339,10 @@
(front.requested_h != temp.requested_h)) {
// the size changed, we need to ask our client to request a new buffer
LOGD_IF(DEBUG_RESIZE,
- "resize (layer=%p), requested (%dx%d), "
- "drawing (%d,%d), (%dx%d), (%dx%d)",
+ "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
this,
int(temp.requested_w), int(temp.requested_h),
- int(front.requested_w), int(front.requested_h),
- int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
- int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
+ int(front.requested_w), int(front.requested_h));
// we're being resized and there is a freeze display request,
// acquire a freeze lock, so that the screen stays put
@@ -486,22 +394,25 @@
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
ssize_t buf = lcblk->retireAndLock();
- if (buf < NO_ERROR) {
- //LOGW("nothing to retire (%s)", strerror(-buf));
- // NOTE: here the buffer is locked because we will used
+ if (buf == NOT_ENOUGH_DATA) {
+ // NOTE: This is not an error, it simply means there is nothing to
+ // retire. The buffer is locked because we will use it
// for composition later in the loop
return;
}
- // ouch, this really should never happen
- if (uint32_t(buf)>=NUM_BUFFERS) {
+ if (buf < NO_ERROR) {
LOGE("retireAndLock() buffer index (%d) out of range", buf);
mPostedDirtyRegion.clear();
return;
}
// we retired a buffer, which becomes the new front buffer
- mFrontBufferIndex = buf;
+ if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
+ LOGE("retireAndLock() buffer index (%d) out of range", buf);
+ mPostedDirtyRegion.clear();
+ return;
+ }
// get the dirty region
sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
@@ -593,10 +504,9 @@
void Layer::finishPageFlip()
{
- status_t err = lcblk->unlock( mFrontBufferIndex );
- LOGE_IF(err!=NO_ERROR,
- "layer %p, buffer=%d wasn't locked!",
- this, mFrontBufferIndex);
+ int buf = mBufferManager.getActiveBufferIndex();
+ status_t err = lcblk->unlock( buf );
+ LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf);
}
@@ -633,6 +543,109 @@
// ---------------------------------------------------------------------------
+Layer::BufferManager::BufferManager(TextureManager& tm)
+ : mTextureManager(tm), mActiveBuffer(0), mFailover(false)
+{
+}
+
+size_t Layer::BufferManager::getBufferCount() const {
+ return NUM_BUFFERS;
+}
+
+// only for debugging
+sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
+ return mBufferData[index].buffer;
+}
+
+status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
+ // TODO: need to validate 'index'
+ mActiveBuffer = index;
+ return NO_ERROR;
+}
+
+size_t Layer::BufferManager::getActiveBufferIndex() const {
+ return mActiveBuffer;
+}
+
+Texture Layer::BufferManager::getActiveTexture() const {
+ return mFailover ? mFailoverTexture : mBufferData[mActiveBuffer].texture;
+}
+
+sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
+ Mutex::Autolock _l(mLock);
+ return mBufferData[mActiveBuffer].buffer;
+}
+
+sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
+{
+ sp<GraphicBuffer> buffer;
+ Mutex::Autolock _l(mLock);
+ buffer = mBufferData[index].buffer;
+ mBufferData[index].buffer = 0;
+ return buffer;
+}
+
+status_t Layer::BufferManager::attachBuffer(size_t index,
+ const sp<GraphicBuffer>& buffer)
+{
+ Mutex::Autolock _l(mLock);
+ mBufferData[index].buffer = buffer;
+ mBufferData[index].texture.dirty = true;
+ return NO_ERROR;
+}
+
+status_t Layer::BufferManager::destroyTexture(Texture* tex, EGLDisplay dpy)
+{
+ if (tex->name != -1U) {
+ glDeleteTextures(1, &tex->name);
+ tex->name = -1U;
+ }
+ if (tex->image != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(dpy, tex->image);
+ tex->image = EGL_NO_IMAGE_KHR;
+ }
+ return NO_ERROR;
+}
+
+status_t Layer::BufferManager::destroy(EGLDisplay dpy)
+{
+ Mutex::Autolock _l(mLock);
+ for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
+ destroyTexture(&mBufferData[i].texture, dpy);
+ mBufferData[i].buffer = 0;
+ }
+ destroyTexture(&mFailoverTexture, dpy);
+ return NO_ERROR;
+}
+
+status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
+ const sp<GraphicBuffer>& buffer)
+{
+ size_t index = mActiveBuffer;
+ Texture& texture(mBufferData[index].texture);
+ status_t err = mTextureManager.initEglImage(&texture, dpy, buffer);
+ // if EGLImage fails, we switch to regular texture mode, and we
+ // free all resources associated with using EGLImages.
+ if (err == NO_ERROR) {
+ mFailover = false;
+ destroyTexture(&mFailoverTexture, dpy);
+ } else {
+ mFailover = true;
+ for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
+ destroyTexture(&mBufferData[i].texture, dpy);
+ }
+ }
+ return err;
+}
+
+status_t Layer::BufferManager::loadTexture(
+ const Region& dirty, const GGLSurface& t)
+{
+ return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
+}
+
+// ---------------------------------------------------------------------------
+
Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
SurfaceID id, const sp<Layer>& owner)
: Surface(flinger, id, owner->getIdentity(), owner)
@@ -648,15 +661,21 @@
sp<GraphicBuffer> buffer;
sp<Layer> owner(getOwner());
if (owner != 0) {
- LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
- "getBuffer() index (%d) out of range", index);
- if (uint32_t(index) < NUM_BUFFERS) {
- buffer = owner->requestBuffer(index, usage);
- }
+ buffer = owner->requestBuffer(index, usage);
}
return buffer;
}
+status_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
+{
+ status_t err = DEAD_OBJECT;
+ sp<Layer> owner(getOwner());
+ if (owner != 0) {
+ err = owner->setBufferCount(bufferCount);
+ }
+ return err;
+}
+
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 98e30d7..80fbd6a 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -31,6 +31,7 @@
#include "LayerBase.h"
#include "Transform.h"
+#include "TextureManager.h"
namespace android {
@@ -41,11 +42,13 @@
// ---------------------------------------------------------------------------
-const size_t NUM_BUFFERS = 2;
-
class Layer : public LayerBaseClient
{
-public:
+public:
+ // lcblk is (almost) only accessed from the main SF thread, in the places
+ // where it's not, a reference to Client must be held
+ SharedBufferServer* lcblk;
+
Layer(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i);
@@ -66,15 +69,14 @@
virtual bool isSecure() const { return mSecure; }
virtual sp<Surface> createSurface() const;
virtual status_t ditch();
+ virtual void onRemoved();
// only for debugging
- inline sp<GraphicBuffer> getBuffer(int i) const { return mBuffers[i]; }
+ inline sp<GraphicBuffer> getBuffer(int i) const { return mBufferManager.getBuffer(i); }
// only for debugging
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
// only for debugging
inline PixelFormat pixelFormat() const { return mFormat; }
- // only for debugging
- inline int getFrontBufferIndex() const { return mFrontBufferIndex; }
virtual const char* getTypeId() const { return "Layer"; }
@@ -82,15 +84,12 @@
virtual void dump(String8& result, char* scratch, size_t size) const;
private:
- inline sp<GraphicBuffer> getFrontBufferLocked() {
- return mBuffers[mFrontBufferIndex];
- }
-
void reloadTexture(const Region& dirty);
uint32_t getEffectiveUsage(uint32_t usage) const;
sp<GraphicBuffer> requestBuffer(int index, int usage);
+ status_t setBufferCount(int bufferCount);
void destroy();
class SurfaceLayer : public LayerBaseClient::Surface {
@@ -100,6 +99,7 @@
~SurfaceLayer();
private:
virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
+ virtual status_t setBufferCount(int bufferCount);
sp<Layer> getOwner() const {
return static_cast<Layer*>(Surface::getOwner().get());
}
@@ -109,22 +109,70 @@
sp<Surface> mSurface;
bool mSecure;
- bool mNoEGLImageForSwBuffers;
int32_t mFrontBufferIndex;
bool mNeedsBlending;
bool mNeedsDithering;
Region mPostedDirtyRegion;
sp<FreezeLock> mFreezeLock;
PixelFormat mFormat;
-
- // protected by mLock
- sp<GraphicBuffer> mBuffers[NUM_BUFFERS];
- Texture mTextures[NUM_BUFFERS];
- sp<GraphicBuffer> mHybridBuffer;
- uint32_t mWidth;
- uint32_t mHeight;
-
- mutable Mutex mLock;
+
+ class BufferManager {
+ static const size_t NUM_BUFFERS = 2;
+ struct BufferData {
+ sp<GraphicBuffer> buffer;
+ Texture texture;
+ };
+ mutable Mutex mLock;
+ BufferData mBufferData[NUM_BUFFERS];
+ Texture mFailoverTexture;
+ TextureManager& mTextureManager;
+ ssize_t mActiveBuffer;
+ bool mFailover;
+ static status_t destroyTexture(Texture* tex, EGLDisplay dpy);
+
+ public:
+ BufferManager(TextureManager& tm);
+
+ size_t getBufferCount() const;
+
+ // detach/attach buffer from/to given index
+ sp<GraphicBuffer> detachBuffer(size_t index);
+ status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
+
+ // ----------------------------------------------
+ // must be called from GL thread
+
+ // set/get active buffer index
+ status_t setActiveBufferIndex(size_t index);
+ size_t getActiveBufferIndex() const;
+
+ // return the active buffer
+ sp<GraphicBuffer> getActiveBuffer() const;
+
+ // return the active texture (or fail-over)
+ Texture getActiveTexture() const;
+
+ // frees resources associated with all buffers
+ status_t destroy(EGLDisplay dpy);
+
+ // load bitmap data into the active buffer
+ status_t loadTexture(const Region& dirty, const GGLSurface& t);
+
+ // make active buffer an EGLImage if needed
+ status_t initEglImage(EGLDisplay dpy,
+ const sp<GraphicBuffer>& buffer);
+
+ // ----------------------------------------------
+ // only for debugging
+ sp<GraphicBuffer> getBuffer(size_t index) const;
+ };
+
+ TextureManager mTextureManager;
+ BufferManager mBufferManager;
+
+ mutable Mutex mLock;
+ uint32_t mWidth;
+ uint32_t mHeight;
};
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 48b0e47..63b9520 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -32,6 +32,7 @@
#include "LayerBase.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+#include "TextureManager.h"
namespace android {
@@ -340,18 +341,6 @@
*/
}
-GLuint LayerBase::createTexture() const
-{
- GLuint textureName = -1;
- glGenTextures(1, &textureName);
- glBindTexture(GL_TEXTURE_2D, textureName);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- return textureName;
-}
-
void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
GLclampx green, GLclampx blue,
GLclampx alpha) const
@@ -492,187 +481,6 @@
}
}
-bool LayerBase::isSupportedYuvFormat(int format) const
-{
- switch (format) {
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_P:
- case HAL_PIXEL_FORMAT_YCbCr_420_P:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- case HAL_PIXEL_FORMAT_YCbCr_420_I:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- return true;
- }
- return false;
-}
-
-void LayerBase::loadTexture(Texture* texture,
- const Region& dirty, const GGLSurface& t) const
-{
- if (texture->name == -1U) {
- // uh?
- return;
- }
-
- glBindTexture(GL_TEXTURE_2D, texture->name);
-
- /*
- * In OpenGL ES we can't specify a stride with glTexImage2D (however,
- * GL_UNPACK_ALIGNMENT is a limited form of stride).
- * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
- * need to do something reasonable (here creating a bigger texture).
- *
- * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
- *
- * This situation doesn't happen often, but some h/w have a limitation
- * for their framebuffer (eg: must be multiple of 8 pixels), and
- * we need to take that into account when using these buffers as
- * textures.
- *
- * This should never be a problem with POT textures
- */
-
- int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
- unpack = 1 << ((unpack > 3) ? 3 : unpack);
- glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
-
- /*
- * round to POT if needed
- */
- if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
- texture->NPOTAdjust = true;
- }
-
- if (texture->NPOTAdjust) {
- // find the smallest power-of-two that will accommodate our surface
- texture->potWidth = 1 << (31 - clz(t.width));
- texture->potHeight = 1 << (31 - clz(t.height));
- if (texture->potWidth < t.width) texture->potWidth <<= 1;
- if (texture->potHeight < t.height) texture->potHeight <<= 1;
- texture->wScale = float(t.width) / texture->potWidth;
- texture->hScale = float(t.height) / texture->potHeight;
- } else {
- texture->potWidth = t.width;
- texture->potHeight = t.height;
- }
-
- Rect bounds(dirty.bounds());
- GLvoid* data = 0;
- if (texture->width != t.width || texture->height != t.height) {
- texture->width = t.width;
- texture->height = t.height;
-
- // texture size changed, we need to create a new one
- bounds.set(Rect(t.width, t.height));
- if (t.width == texture->potWidth &&
- t.height == texture->potHeight) {
- // we can do it one pass
- data = t.data;
- }
-
- if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGB, texture->potWidth, texture->potHeight, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture->potWidth, texture->potHeight, 0,
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_RGBA, texture->potWidth, texture->potHeight, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else if (isSupportedYuvFormat(t.format)) {
- // just show the Y plane of YUV buffers
- glTexImage2D(GL_TEXTURE_2D, 0,
- GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
- } else {
- // oops, we don't handle this format!
- LOGE("layer %p, texture=%d, using format %d, which is not "
- "supported by the GL", this, texture->name, t.format);
- }
- }
- if (!data) {
- if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
- t.data + bounds.top*t.stride*2);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
- t.data + bounds.top*t.stride*2);
- } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_RGBA, GL_UNSIGNED_BYTE,
- t.data + bounds.top*t.stride*4);
- } else if (isSupportedYuvFormat(t.format)) {
- // just show the Y plane of YUV buffers
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, bounds.top, t.width, bounds.height(),
- GL_LUMINANCE, GL_UNSIGNED_BYTE,
- t.data + bounds.top*t.stride);
- }
- }
-}
-
-status_t LayerBase::initializeEglImage(
- const sp<GraphicBuffer>& buffer, Texture* texture)
-{
- status_t err = NO_ERROR;
-
- // we need to recreate the texture
- EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-
- // free the previous image
- if (texture->image != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(dpy, texture->image);
- texture->image = EGL_NO_IMAGE_KHR;
- }
-
- // construct an EGL_NATIVE_BUFFER_ANDROID
- android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
-
- // create the new EGLImageKHR
- const EGLint attrs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE, EGL_NONE
- };
- texture->image = eglCreateImageKHR(
- dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
- (EGLClientBuffer)clientBuf, attrs);
-
- if (texture->image != EGL_NO_IMAGE_KHR) {
- glBindTexture(GL_TEXTURE_2D, texture->name);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
- (GLeglImageOES)texture->image);
- GLint error = glGetError();
- if (UNLIKELY(error != GL_NO_ERROR)) {
- LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
- "failed err=0x%04x",
- this, texture->image, error);
- err = INVALID_OPERATION;
- } else {
- // Everything went okay!
- texture->NPOTAdjust = false;
- texture->dirty = false;
- texture->width = clientBuf->width;
- texture->height = clientBuf->height;
- }
- } else {
- LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x",
- this, eglGetError());
- err = INVALID_OPERATION;
- }
- return err;
-}
-
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
{
const Layer::State& s(drawingState());
@@ -696,12 +504,9 @@
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
- : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
+ : LayerBase(flinger, display), client(client), mIndex(i),
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
- lcblk = new SharedBufferServer(
- client->ctrlblk, i, NUM_BUFFERS,
- mIdentity);
}
void LayerBaseClient::onFirstRef()
@@ -718,7 +523,6 @@
if (client != 0) {
client->free(mIndex);
}
- delete lcblk;
}
ssize_t LayerBaseClient::serverIndex() const
@@ -748,14 +552,6 @@
const_cast<LayerBaseClient *>(this));
}
-// called with SurfaceFlinger::mStateLock as soon as the layer is entered
-// in the purgatory list
-void LayerBaseClient::onRemoved()
-{
- // wake up the condition
- lcblk->setStatus(NO_INIT);
-}
-
void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBase::dump(result, buffer, SIZE);
@@ -825,6 +621,11 @@
return NULL;
}
+status_t LayerBaseClient::Surface::setBufferCount(int bufferCount)
+{
+ return INVALID_OPERATION;
+}
+
status_t LayerBaseClient::Surface::registerBuffers(
const ISurface::BufferHeap& buffers)
{
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 219a53c..53b848f 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -46,6 +46,7 @@
class GraphicBuffer;
class GraphicPlane;
class SurfaceFlinger;
+class Texture;
// ---------------------------------------------------------------------------
@@ -221,35 +222,10 @@
const GraphicPlane& graphicPlane(int dpy) const;
GraphicPlane& graphicPlane(int dpy);
- GLuint createTexture() const;
-
- struct Texture {
- Texture() : name(-1U), width(0), height(0),
- image(EGL_NO_IMAGE_KHR), transform(0),
- NPOTAdjust(false), dirty(true) { }
- GLuint name;
- GLuint width;
- GLuint height;
- GLuint potWidth;
- GLuint potHeight;
- GLfloat wScale;
- GLfloat hScale;
- EGLImageKHR image;
- uint32_t transform;
- bool NPOTAdjust;
- bool dirty;
- };
-
void clearWithOpenGL(const Region& clip, GLclampx r, GLclampx g,
GLclampx b, GLclampx alpha) const;
void clearWithOpenGL(const Region& clip) const;
void drawWithOpenGL(const Region& clip, const Texture& texture) const;
- void loadTexture(Texture* texture,
- const Region& dirty, const GGLSurface& t) const;
- status_t initializeEglImage(
- const sp<GraphicBuffer>& buffer, Texture* texture);
-
- bool isSupportedYuvFormat(int format) const;
sp<SurfaceFlinger> mFlinger;
uint32_t mFlags;
@@ -294,10 +270,6 @@
public:
class Surface;
- // lcblk is (almost) only accessed from the main SF thread, in the places
- // where it's not, a reference to Client must be held
- SharedBufferServer* lcblk;
-
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i);
virtual ~LayerBaseClient();
@@ -311,7 +283,6 @@
sp<Surface> getSurface();
virtual sp<Surface> createSurface() const;
virtual ssize_t serverIndex() const;
- virtual void onRemoved();
virtual const char* getTypeId() const { return "LayerBaseClient"; }
class Surface : public BnSurface
@@ -331,6 +302,8 @@
private:
virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
+ virtual status_t setBufferCount(int bufferCount);
+
virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
virtual void postBuffer(ssize_t offset);
virtual void unregisterBuffers();
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 0041a0f..dfcc80f 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -328,7 +328,7 @@
LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
const ISurface::BufferHeap& buffers)
: Source(layer), mStatus(NO_ERROR), mBufferSize(0),
- mUseEGLImageDirectly(true)
+ mTextureManager(layer.mFlags)
{
if (buffers.heap == NULL) {
// this is allowed, but in this case, it is illegal to receive
@@ -460,35 +460,10 @@
NativeBuffer src(ourBuffer->getBuffer());
const Rect transformedBounds(mLayer.getTransformedBounds());
- if (UNLIKELY(mTexture.name == -1LU)) {
- mTexture.name = mLayer.createTexture();
- }
-
#if defined(EGL_ANDROID_image_native_buffer)
if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
err = INVALID_OPERATION;
if (ourBuffer->supportsCopybit()) {
-
- // there are constraints on buffers used by the GPU and these may not
- // be honored here. We need to change the API so the buffers
- // are allocated with gralloc. For now disable this code-path
-#if 0
- // First, try to use the buffer as an EGLImage directly
- if (mUseEGLImageDirectly) {
- // NOTE: Assume the buffer is allocated with the proper USAGE flags
-
- sp<GraphicBuffer> buffer = new GraphicBuffer(
- src.img.w, src.img.h, src.img.format,
- GraphicBuffer::USAGE_HW_TEXTURE,
- src.img.w, src.img.handle, false);
-
- err = mLayer.initializeEglImage(buffer, &mTexture);
- if (err != NO_ERROR) {
- mUseEGLImageDirectly = false;
- }
- }
-#endif
-
copybit_device_t* copybit = mLayer.mBlitEngine;
if (copybit && err != NO_ERROR) {
// create our EGLImageKHR the first time
@@ -525,7 +500,7 @@
t.format = src.img.format;
t.data = (GGLubyte*)src.img.base;
const Region dirty(Rect(t.width, t.height));
- mLayer.loadTexture(&mTexture, dirty, t);
+ mTextureManager.loadTexture(&mTexture, dirty, t);
}
mTexture.transform = mBufferHeap.transform;
@@ -591,7 +566,8 @@
dst.crop.r = w;
dst.crop.b = h;
- err = mLayer.initializeEglImage(buffer, &mTexture);
+ EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
+ err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
}
return err;
@@ -607,7 +583,6 @@
glDeleteTextures(1, &mTexture.name);
Texture defaultTexture;
mTexture = defaultTexture;
- mTexture.name = mLayer.createTexture();
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 243cc43..869c74f 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include "LayerBase.h"
+#include "TextureManager.h"
struct copybit_device_t;
@@ -139,9 +140,9 @@
status_t mStatus;
ISurface::BufferHeap mBufferHeap;
size_t mBufferSize;
- mutable LayerBase::Texture mTexture;
+ mutable Texture mTexture;
mutable NativeBuffer mTempBuffer;
- mutable bool mUseEGLImageDirectly;
+ mutable TextureManager mTextureManager;
};
class OverlaySource : public Source {
diff --git a/libs/surfaceflinger/TextureManager.cpp b/libs/surfaceflinger/TextureManager.cpp
new file mode 100644
index 0000000..e5d5302
--- /dev/null
+++ b/libs/surfaceflinger/TextureManager.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <hardware/hardware.h>
+
+#include "clz.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "TextureManager.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+TextureManager::TextureManager(uint32_t flags)
+ : mFlags(flags)
+{
+}
+
+GLuint TextureManager::createTexture()
+{
+ GLuint textureName = -1;
+ glGenTextures(1, &textureName);
+ glBindTexture(GL_TEXTURE_2D, textureName);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ return textureName;
+}
+
+bool TextureManager::isSupportedYuvFormat(int format)
+{
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_P:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_YCbCr_420_I:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return true;
+ }
+ return false;
+}
+
+status_t TextureManager::initEglImage(Texture* texture,
+ EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
+{
+ status_t err = NO_ERROR;
+ if (!texture->dirty) return err;
+
+ // free the previous image
+ if (texture->image != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(dpy, texture->image);
+ texture->image = EGL_NO_IMAGE_KHR;
+ }
+
+ // construct an EGL_NATIVE_BUFFER_ANDROID
+ android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+
+ // create the new EGLImageKHR
+ const EGLint attrs[] = {
+ EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE, EGL_NONE
+ };
+ texture->image = eglCreateImageKHR(
+ dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+ (EGLClientBuffer)clientBuf, attrs);
+
+ if (texture->image != EGL_NO_IMAGE_KHR) {
+ if (texture->name == -1UL) {
+ texture->name = createTexture();
+ texture->width = 0;
+ texture->height = 0;
+ }
+ glBindTexture(GL_TEXTURE_2D, texture->name);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
+ (GLeglImageOES)texture->image);
+ GLint error = glGetError();
+ if (error != GL_NO_ERROR) {
+ LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
+ texture->image, error);
+ err = INVALID_OPERATION;
+ } else {
+ // Everything went okay!
+ texture->NPOTAdjust = false;
+ texture->dirty = false;
+ texture->width = clientBuf->width;
+ texture->height = clientBuf->height;
+ }
+ } else {
+ LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
+ err = INVALID_OPERATION;
+ }
+ return err;
+}
+
+status_t TextureManager::loadTexture(Texture* texture,
+ const Region& dirty, const GGLSurface& t)
+{
+ if (texture->name == -1UL) {
+ texture->name = createTexture();
+ texture->width = 0;
+ texture->height = 0;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, texture->name);
+
+ /*
+ * In OpenGL ES we can't specify a stride with glTexImage2D (however,
+ * GL_UNPACK_ALIGNMENT is a limited form of stride).
+ * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
+ * need to do something reasonable (here creating a bigger texture).
+ *
+ * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
+ *
+ * This situation doesn't happen often, but some h/w have a limitation
+ * for their framebuffer (eg: must be multiple of 8 pixels), and
+ * we need to take that into account when using these buffers as
+ * textures.
+ *
+ * This should never be a problem with POT textures
+ */
+
+ int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
+ unpack = 1 << ((unpack > 3) ? 3 : unpack);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
+
+ /*
+ * round to POT if needed
+ */
+ if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+ texture->NPOTAdjust = true;
+ }
+
+ if (texture->NPOTAdjust) {
+ // find the smallest power-of-two that will accommodate our surface
+ texture->potWidth = 1 << (31 - clz(t.width));
+ texture->potHeight = 1 << (31 - clz(t.height));
+ if (texture->potWidth < t.width) texture->potWidth <<= 1;
+ if (texture->potHeight < t.height) texture->potHeight <<= 1;
+ texture->wScale = float(t.width) / texture->potWidth;
+ texture->hScale = float(t.height) / texture->potHeight;
+ } else {
+ texture->potWidth = t.width;
+ texture->potHeight = t.height;
+ }
+
+ Rect bounds(dirty.bounds());
+ GLvoid* data = 0;
+ if (texture->width != t.width || texture->height != t.height) {
+ texture->width = t.width;
+ texture->height = t.height;
+
+ // texture size changed, we need to create a new one
+ bounds.set(Rect(t.width, t.height));
+ if (t.width == texture->potWidth &&
+ t.height == texture->potHeight) {
+ // we can do it one pass
+ data = t.data;
+ }
+
+ if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ GL_RGB, texture->potWidth, texture->potHeight, 0,
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ GL_RGBA, texture->potWidth, texture->potHeight, 0,
+ GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+ t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ GL_RGBA, texture->potWidth, texture->potHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, data);
+ } else if (isSupportedYuvFormat(t.format)) {
+ // just show the Y plane of YUV buffers
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
+ GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+ } else {
+ // oops, we don't handle this format!
+ LOGE("texture=%d, using format %d, which is not "
+ "supported by the GL", texture->name, t.format);
+ }
+ }
+ if (!data) {
+ if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, bounds.top, t.width, bounds.height(),
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+ t.data + bounds.top*t.stride*2);
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, bounds.top, t.width, bounds.height(),
+ GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+ t.data + bounds.top*t.stride*2);
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+ t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, bounds.top, t.width, bounds.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ t.data + bounds.top*t.stride*4);
+ } else if (isSupportedYuvFormat(t.format)) {
+ // just show the Y plane of YUV buffers
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, bounds.top, t.width, bounds.height(),
+ GL_LUMINANCE, GL_UNSIGNED_BYTE,
+ t.data + bounds.top*t.stride);
+ }
+ }
+ return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/TextureManager.h b/libs/surfaceflinger/TextureManager.h
new file mode 100644
index 0000000..90cb62b
--- /dev/null
+++ b/libs/surfaceflinger/TextureManager.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TEXTURE_MANAGER_H
+#define ANDROID_TEXTURE_MANAGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+
+#include <ui/Region.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class GraphicBuffer;
+
+// ---------------------------------------------------------------------------
+
+struct Texture {
+ Texture() : name(-1U), width(0), height(0),
+ image(EGL_NO_IMAGE_KHR), transform(0),
+ NPOTAdjust(false), dirty(true) { }
+ GLuint name;
+ GLuint width;
+ GLuint height;
+ GLuint potWidth;
+ GLuint potHeight;
+ GLfloat wScale;
+ GLfloat hScale;
+ EGLImageKHR image;
+ uint32_t transform;
+ bool NPOTAdjust;
+ bool dirty;
+};
+
+// ---------------------------------------------------------------------------
+
+class TextureManager {
+ uint32_t mFlags;
+ GLuint createTexture();
+ static bool isSupportedYuvFormat(int format);
+public:
+
+ TextureManager(uint32_t flags);
+
+ // load bitmap data into the active buffer
+ status_t loadTexture(Texture* texture,
+ const Region& dirty, const GGLSurface& t);
+
+ // make active buffer an EGLImage if needed
+ status_t initEglImage(Texture* texture,
+ EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_TEXTURE_MANAGER_H
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/surfaceflinger_client/ISurface.cpp
index bb86199..c5d0c0e 100644
--- a/libs/surfaceflinger_client/ISurface.cpp
+++ b/libs/surfaceflinger_client/ISurface.cpp
@@ -83,6 +83,16 @@
return buffer;
}
+ virtual status_t setBufferCount(int bufferCount)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+ data.writeInt32(bufferCount);
+ remote()->transact(SET_BUFFER_COUNT, data, &reply);
+ status_t err = reply.readInt32();
+ return err;
+ }
+
virtual status_t registerBuffers(const BufferHeap& buffers)
{
Parcel data, reply;
@@ -146,6 +156,13 @@
return BAD_VALUE;
return reply->write(*buffer);
}
+ case SET_BUFFER_COUNT: {
+ CHECK_INTERFACE(ISurface, data, reply);
+ int bufferCount = data.readInt32();
+ status_t err = setBufferCount(bufferCount);
+ reply->writeInt32(err);
+ return NO_ERROR;
+ }
case REGISTER_BUFFERS: {
CHECK_INTERFACE(ISurface, data, reply);
BufferHeap buffer;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index c42cd53..4a98026 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -305,7 +305,6 @@
: UpdateBase(sbb), numBuffers(numBuffers) {
}
ssize_t SharedBufferServer::RetireUpdate::operator()() {
- // head is only written in this function, which is single-thread.
int32_t head = stack.head;
if (uint32_t(head) >= NUM_BUFFER_MAX)
return BAD_VALUE;
@@ -322,16 +321,14 @@
}
} while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
- // update the head pointer
- head = ((head+1 >= numBuffers) ? 0 : head+1);
-
// lock the buffer before advancing head, which automatically unlocks
// the buffer we preventively locked upon entering this function
+ head = (head + 1) % numBuffers;
android_atomic_write(stack.index[head], &stack.inUse);
- // advance head
+ // head is only modified here, so we don't need to use cmpxchg
android_atomic_write(head, &stack.head);
-
+
// now that head has moved, we can increment the number of available buffers
android_atomic_inc(&stack.available);
return head;
@@ -450,6 +447,14 @@
return stack.setDirtyRegion(buf, reg);
}
+status_t SharedBufferClient::setBufferCount(int bufferCount)
+{
+ if (uint32_t(bufferCount) >= NUM_BUFFER_MAX)
+ return BAD_VALUE;
+ mNumBuffers = bufferCount;
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
@@ -463,6 +468,7 @@
mSharedStack->reallocMask = 0;
memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
for (int i=0 ; i<num ; i++) {
+ mBufferList.add(i);
mSharedStack->index[i] = i;
}
}
@@ -513,6 +519,7 @@
status_t SharedBufferServer::assertReallocate(int buf)
{
+ // TODO: need to validate "buf"
ReallocateCondition condition(this, buf);
status_t err = waitForCondition(condition);
return err;
@@ -524,12 +531,85 @@
return stack.getDirtyRegion(buf);
}
+
+/*
+ *
+ * NOTE: this is not thread-safe on the server-side, meaning
+ * 'head' cannot move during this operation. The client-side
+ * can safely operate an usual.
+ *
+ */
+status_t SharedBufferServer::resize(int newNumBuffers)
+{
+ if (uint32_t(newNumBuffers) >= NUM_BUFFER_MAX)
+ return BAD_VALUE;
+
+ // for now we're not supporting shrinking
+ const int numBuffers = mNumBuffers;
+ if (newNumBuffers < numBuffers)
+ return BAD_VALUE;
+
+ SharedBufferStack& stack( *mSharedStack );
+ const int extra = newNumBuffers - numBuffers;
+
+ // read the head, make sure it's valid
+ int32_t head = stack.head;
+ if (uint32_t(head) >= NUM_BUFFER_MAX)
+ return BAD_VALUE;
+
+ int base = numBuffers;
+ int32_t avail = stack.available;
+ int tail = head - avail + 1;
+ if (tail >= 0) {
+ int8_t* const index = const_cast<int8_t*>(stack.index);
+ const int nb = numBuffers - head;
+ memmove(&index[head + extra], &index[head], nb);
+ base = head;
+ // move head 'extra' ahead, this doesn't impact stack.index[head];
+ stack.head = head + extra;
+ }
+ stack.available += extra;
+
+ // fill the new free space with unused buffers
+ BufferList::const_iterator curr(mBufferList.free_begin());
+ for (int i=0 ; i<extra ; i++) {
+ stack.index[base+i] = *curr++;
+ mBufferList.add(stack.index[base+i]);
+ }
+
+ mNumBuffers = newNumBuffers;
+ return NO_ERROR;
+}
+
SharedBufferStack::Statistics SharedBufferServer::getStats() const
{
SharedBufferStack& stack( *mSharedStack );
return stack.stats;
}
+// ---------------------------------------------------------------------------
+status_t SharedBufferServer::BufferList::add(int value)
+{
+ if (uint32_t(value) >= mCapacity)
+ return BAD_VALUE;
+ uint32_t mask = 1<<(31-value);
+ if (mList & mask)
+ return ALREADY_EXISTS;
+ mList |= mask;
+ return NO_ERROR;
+}
+
+status_t SharedBufferServer::BufferList::remove(int value)
+{
+ if (uint32_t(value) >= mCapacity)
+ return BAD_VALUE;
+ uint32_t mask = 1<<(31-value);
+ if (!(mList & mask))
+ return NAME_NOT_FOUND;
+ mList &= ~mask;
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index eee4dae..afbeafb 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -673,6 +673,27 @@
return NO_ERROR;
}
+int Surface::setBufferCount(int bufferCount)
+{
+ sp<ISurface> s(mSurface);
+ if (s == 0) return NO_INIT;
+
+ // FIXME: this needs to be synchronized dequeue/queue
+
+ status_t err = s->setBufferCount(bufferCount);
+ LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
+ bufferCount, strerror(-err));
+ if (err == NO_ERROR) {
+ err = mSharedBufferClient->getStatus();
+ LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err);
+ if (!err) {
+ // update our local copy of the buffer count
+ mSharedBufferClient->setBufferCount(bufferCount);
+ }
+ }
+ return err;
+}
+
// ----------------------------------------------------------------------------
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index 5a05e6a..60a0d82 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -824,7 +824,7 @@
// TODO: look for previously-created shared memory slice?
int method;
- long uncompressedLen;
+ size_t uncompressedLen;
//printf("USING Zip '%s'\n", pEntry->getFileName());
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
index 45f6c8b..16b219ca 100644
--- a/libs/utils/ZipFileCRO.cpp
+++ b/libs/utils/ZipFileCRO.cpp
@@ -39,8 +39,8 @@
}
bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
- int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+ int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
ZipFileRO* zip = (ZipFileRO*)zipToken;
ZipEntryRO entry = (ZipEntryRO)entryToken;
return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index 6c701dd..28dc512 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -29,6 +29,22 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
+#include <unistd.h>
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({ \
+ typeof (exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+#endif
using namespace android;
@@ -38,6 +54,7 @@
#define kEOCDSignature 0x06054b50
#define kEOCDLen 22
#define kEOCDNumEntries 8 // offset to #of entries in file
+#define kEOCDSize 12 // size of the central directory
#define kEOCDFileOffset 16 // offset to central directory
#define kMaxCommentLen 65535 // longest possible in ushort
@@ -90,9 +107,8 @@
status_t ZipFileRO::open(const char* zipFileName)
{
int fd = -1;
- off_t length;
- assert(mFileMap == NULL);
+ assert(mDirectoryMap == NULL);
/*
* Open and map the specified file.
@@ -103,172 +119,240 @@
return NAME_NOT_FOUND;
}
- length = lseek(fd, 0, SEEK_END);
- if (length < 0) {
+ mFileLength = lseek(fd, 0, SEEK_END);
+ if (mFileLength < kEOCDLen) {
close(fd);
return UNKNOWN_ERROR;
}
- mFileMap = new FileMap();
- if (mFileMap == NULL) {
- close(fd);
- return NO_MEMORY;
+ if (mFileName != NULL) {
+ free(mFileName);
}
- if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
- LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
- close(fd);
- return UNKNOWN_ERROR;
- }
+ mFileName = strdup(zipFileName);
mFd = fd;
/*
- * Got it mapped, verify it and create data structures for fast access.
+ * Find the Central Directory and store its size and number of entries.
+ */
+ if (!mapCentralDirectory()) {
+ goto bail;
+ }
+
+ /*
+ * Verify Central Directory and create data structures for fast access.
*/
if (!parseZipArchive()) {
- mFileMap->release();
- mFileMap = NULL;
- return UNKNOWN_ERROR;
+ goto bail;
}
return OK;
+
+bail:
+ free(mFileName);
+ mFileName = NULL;
+ close(fd);
+ return UNKNOWN_ERROR;
}
/*
* Parse the Zip archive, verifying its contents and initializing internal
* data structures.
*/
+bool ZipFileRO::mapCentralDirectory(void)
+{
+ size_t readAmount = kMaxEOCDSearch;
+ if (readAmount > (size_t) mFileLength)
+ readAmount = mFileLength;
+
+ unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
+ if (scanBuf == NULL) {
+ LOGW("couldn't allocate scanBuf: %s", strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ /*
+ * Make sure this is a Zip archive.
+ */
+ if (lseek(mFd, 0, SEEK_SET) != 0) {
+ LOGW("seek to start failed: %s", strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
+ if (actual != (ssize_t) sizeof(int32_t)) {
+ LOGI("couldn't read first signature from zip archive: %s", strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ {
+ unsigned int header = get4LE(scanBuf);
+ if (header == kEOCDSignature) {
+ LOGI("Found Zip archive, but it looks empty\n");
+ free(scanBuf);
+ return false;
+ } else if (header != kLFHSignature) {
+ LOGV("Not a Zip archive (found 0x%08x)\n", val);
+ free(scanBuf);
+ return false;
+ }
+ }
+
+ /*
+ * Perform the traditional EOCD snipe hunt.
+ *
+ * We're searching for the End of Central Directory magic number,
+ * which appears at the start of the EOCD block. It's followed by
+ * 18 bytes of EOCD stuff and up to 64KB of archive comment. We
+ * need to read the last part of the file into a buffer, dig through
+ * it to find the magic number, parse some values out, and use those
+ * to determine the extent of the CD.
+ *
+ * We start by pulling in the last part of the file.
+ */
+ off_t searchStart = mFileLength - readAmount;
+
+ if (lseek(mFd, searchStart, SEEK_SET) != searchStart) {
+ LOGW("seek %ld failed: %s\n", (long) searchStart, strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+ actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
+ if (actual != (ssize_t) readAmount) {
+ LOGW("Zip: read %zd failed: %s\n", readAmount, strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ /*
+ * Scan backward for the EOCD magic. In an archive without a trailing
+ * comment, we'll find it on the first try. (We may want to consider
+ * doing an initial minimal read; if we don't find it, retry with a
+ * second read as above.)
+ */
+ int i;
+ for (i = readAmount - kEOCDLen; i >= 0; i--) {
+ if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
+ LOGV("+++ Found EOCD at buf+%d\n", i);
+ break;
+ }
+ }
+ if (i < 0) {
+ LOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
+ free(scanBuf);
+ return false;
+ }
+
+ off_t eocdOffset = searchStart + i;
+ const unsigned char* eocdPtr = scanBuf + i;
+
+ assert(eocdOffset < mFileLength);
+
+ /*
+ * Grab the CD offset and size, and the number of entries in the
+ * archive. Verify that they look reasonable.
+ */
+ unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
+ unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
+ unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
+
+ if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
+ LOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
+ (long) dirOffset, dirSize, (long) eocdOffset);
+ free(scanBuf);
+ return false;
+ }
+ if (numEntries == 0) {
+ LOGW("empty archive?\n");
+ free(scanBuf);
+ return false;
+ }
+
+ LOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+ numEntries, dirSize, dirOffset);
+
+ mDirectoryMap = new FileMap();
+ if (mDirectoryMap == NULL) {
+ LOGW("Unable to create directory map: %s", strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
+ LOGW("Unable to map '%s' (%zd to %zd): %s\n", mFileName,
+ dirOffset, dirOffset + dirSize, strerror(errno));
+ free(scanBuf);
+ return false;
+ }
+
+ mNumEntries = numEntries;
+ mDirectoryOffset = dirOffset;
+
+ return true;
+}
+
bool ZipFileRO::parseZipArchive(void)
{
-#define CHECK_OFFSET(_off) { \
- if ((unsigned int) (_off) >= maxOffset) { \
- LOGE("ERROR: bad offset %u (max %d): %s\n", \
- (unsigned int) (_off), maxOffset, #_off); \
- goto bail; \
- } \
- }
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- const unsigned char* ptr;
- size_t length = mFileMap->getDataLength();
bool result = false;
- unsigned int i, numEntries, cdOffset;
- unsigned int val;
-
- /*
- * The first 4 bytes of the file will either be the local header
- * signature for the first file (kLFHSignature) or, if the archive doesn't
- * have any files in it, the end-of-central-directory signature
- * (kEOCDSignature).
- */
- val = get4LE(basePtr);
- if (val == kEOCDSignature) {
- LOGI("Found Zip archive, but it looks empty\n");
- goto bail;
- } else if (val != kLFHSignature) {
- LOGV("Not a Zip archive (found 0x%08x)\n", val);
- goto bail;
- }
-
- /*
- * Find the EOCD. We'll find it immediately unless they have a file
- * comment.
- */
- ptr = basePtr + length - kEOCDLen;
-
- while (ptr >= basePtr) {
- if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
- break;
- ptr--;
- }
- if (ptr < basePtr) {
- LOGI("Could not find end-of-central-directory in Zip\n");
- goto bail;
- }
-
- /*
- * There are two interesting items in the EOCD block: the number of
- * entries in the file, and the file offset of the start of the
- * central directory.
- *
- * (There's actually a count of the #of entries in this file, and for
- * all files which comprise a spanned archive, but for our purposes
- * we're only interested in the current file. Besides, we expect the
- * two to be equivalent for our stuff.)
- */
- numEntries = get2LE(ptr + kEOCDNumEntries);
- cdOffset = get4LE(ptr + kEOCDFileOffset);
-
- /* valid offsets are [0,EOCD] */
- unsigned int maxOffset;
- maxOffset = (ptr - basePtr) +1;
-
- LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
- if (numEntries == 0 || cdOffset >= length) {
- LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
- numEntries, cdOffset, length);
- goto bail;
- }
+ const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
+ size_t cdLength = mDirectoryMap->getDataLength();
+ int numEntries = mNumEntries;
/*
* Create hash table. We have a minimum 75% load factor, possibly as
* low as 50% after we round off to a power of 2.
*/
- mNumEntries = numEntries;
- mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
- mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
+ mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
+ mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
/*
* Walk through the central directory, adding entries to the hash
* table.
*/
- ptr = basePtr + cdOffset;
- for (i = 0; i < numEntries; i++) {
- unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
- const unsigned char* localHdr;
- unsigned int hash;
-
+ const unsigned char* ptr = cdPtr;
+ for (int i = 0; i < numEntries; i++) {
if (get4LE(ptr) != kCDESignature) {
LOGW("Missed a central dir sig (at %d)\n", i);
goto bail;
}
- if (ptr + kCDELen > basePtr + length) {
+ if (ptr + kCDELen > cdPtr + cdLength) {
LOGW("Ran off the end (at %d)\n", i);
goto bail;
}
- localHdrOffset = get4LE(ptr + kCDELocalOffset);
- CHECK_OFFSET(localHdrOffset);
+ long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
+ if (localHdrOffset >= mDirectoryOffset) {
+ LOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
+ goto bail;
+ }
+
+ unsigned int fileNameLen, extraLen, commentLen, hash;
+
fileNameLen = get2LE(ptr + kCDENameLen);
extraLen = get2LE(ptr + kCDEExtraLen);
commentLen = get2LE(ptr + kCDECommentLen);
- //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
- // i, localHdrOffset, fileNameLen, extraLen, commentLen);
- //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
-
/* add the CDE filename to the hash table */
hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
- localHdr = basePtr + localHdrOffset;
- if (get4LE(localHdr) != kLFHSignature) {
- LOGW("Bad offset to local header: %d (at %d)\n",
- localHdrOffset, i);
+ ptr += kCDELen + fileNameLen + extraLen + commentLen;
+ if ((size_t)(ptr - cdPtr) > cdLength) {
+ LOGW("bad CD advance (%d vs %zd) at entry %d\n",
+ (int) (ptr - cdPtr), cdLength, i);
goto bail;
}
-
- ptr += kCDELen + fileNameLen + extraLen + commentLen;
- CHECK_OFFSET(ptr - basePtr);
}
-
+ LOGV("+++ zip good scan %d entries\n", numEntries);
result = true;
bail:
return result;
-#undef CHECK_OFFSET
}
-
/*
* Simple string hash function for non-null-terminated strings.
*/
@@ -315,7 +399,7 @@
memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
{
/* match */
- return (ZipEntryRO) (ent + kZipEntryAdj);
+ return (ZipEntryRO)(long)(ent + kZipEntryAdj);
}
ent = (ent + 1) & (mHashTableSize-1);
@@ -354,20 +438,24 @@
* Returns "false" if the offsets to the fields or the contents of the fields
* appear to be bogus.
*/
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
- long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+ size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
{
- int ent = entryToIndex(entry);
+ bool ret = false;
+
+ const int ent = entryToIndex(entry);
if (ent < 0)
return false;
+ HashEntry hashEntry = mHashTable[ent];
+
/*
* Recover the start of the central directory entry from the filename
- * pointer.
+ * pointer. The filename is the first entry past the fixed-size data,
+ * so we can just subtract back from that.
*/
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
- const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
- size_t zipLength = mFileMap->getDataLength();
+ const unsigned char* ptr = (const unsigned char*) hashEntry.name;
+ off_t cdOffset = mDirectoryOffset;
ptr -= kCDELen;
@@ -380,48 +468,78 @@
if (pCrc32 != NULL)
*pCrc32 = get4LE(ptr + kCDECRC);
+ size_t compLen = get4LE(ptr + kCDECompLen);
+ if (pCompLen != NULL)
+ *pCompLen = compLen;
+ size_t uncompLen = get4LE(ptr + kCDEUncompLen);
+ if (pUncompLen != NULL)
+ *pUncompLen = uncompLen;
+
/*
- * We need to make sure that the lengths are not so large that somebody
- * trying to map the compressed or uncompressed data runs off the end
- * of the mapped region.
+ * If requested, determine the offset of the start of the data. All we
+ * have is the offset to the Local File Header, which is variable size,
+ * so we have to read the contents of the struct to figure out where
+ * the actual data starts.
+ *
+ * We also need to make sure that the lengths are not so large that
+ * somebody trying to map the compressed or uncompressed data runs
+ * off the end of the mapped region.
+ *
+ * Note we don't verify compLen/uncompLen if they don't request the
+ * dataOffset, because dataOffset is expensive to determine. However,
+ * if they don't have the file offset, they're not likely to be doing
+ * anything with the contents.
*/
- unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
- if (localHdrOffset + kLFHLen >= zipLength) {
- LOGE("ERROR: bad local hdr offset in zip\n");
- return false;
- }
- const unsigned char* localHdr = basePtr + localHdrOffset;
- off_t dataOffset = localHdrOffset + kLFHLen
- + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
- if ((unsigned long) dataOffset >= zipLength) {
- LOGE("ERROR: bad data offset in zip\n");
- return false;
- }
-
- if (pCompLen != NULL) {
- *pCompLen = get4LE(ptr + kCDECompLen);
- if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
- LOGE("ERROR: bad compressed length in zip\n");
- return false;
- }
- }
- if (pUncompLen != NULL) {
- *pUncompLen = get4LE(ptr + kCDEUncompLen);
- if (*pUncompLen < 0) {
- LOGE("ERROR: negative uncompressed length in zip\n");
- return false;
- }
- if (method == kCompressStored &&
- (size_t)(dataOffset + *pUncompLen) >= zipLength)
- {
- LOGE("ERROR: bad uncompressed length in zip\n");
- return false;
- }
- }
-
if (pOffset != NULL) {
+ long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+ if (localHdrOffset + kLFHLen >= cdOffset) {
+ LOGE("ERROR: bad local hdr offset in zip\n");
+ return false;
+ }
+
+ unsigned char lfhBuf[kLFHLen];
+ if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+ LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+ return false;
+ }
+ ssize_t actual =
+ TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+ if (actual != sizeof(lfhBuf)) {
+ LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+ return false;
+ }
+
+ if (get4LE(lfhBuf) != kLFHSignature) {
+ LOGW("didn't find signature at start of lfh, offset=%ld\n",
+ localHdrOffset);
+ return false;
+ }
+
+ off_t dataOffset = localHdrOffset + kLFHLen
+ + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
+ if (dataOffset >= cdOffset) {
+ LOGW("bad data offset %ld in zip\n", (long) dataOffset);
+ return false;
+ }
+
+ /* check lengths */
+ if ((off_t)(dataOffset + compLen) > cdOffset) {
+ LOGW("bad compressed length in zip (%ld + %zd > %ld)\n",
+ (long) dataOffset, compLen, (long) cdOffset);
+ return false;
+ }
+
+ if (method == kCompressStored &&
+ (off_t)(dataOffset + uncompLen) > cdOffset)
+ {
+ LOGE("ERROR: bad uncompressed length in zip (%ld + %zd > %ld)\n",
+ (long) dataOffset, uncompLen, (long) cdOffset);
+ return false;
+ }
+
*pOffset = dataOffset;
}
+
return true;
}
@@ -457,14 +575,14 @@
*/
FileMap* newMap;
- long compLen;
+ size_t compLen;
off_t offset;
if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
return NULL;
newMap = new FileMap();
- if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, true)) {
+ if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
newMap->release();
return NULL;
}
@@ -480,19 +598,26 @@
*/
bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
{
- const int kSequentialMin = 32768;
+ const size_t kSequentialMin = 32768;
bool result = false;
int ent = entryToIndex(entry);
if (ent < 0)
return -1;
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
int method;
- long uncompLen, compLen;
+ size_t uncompLen, compLen;
off_t offset;
+ const unsigned char* ptr;
getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
+ FileMap* file = createEntryFileMap(entry);
+ if (file == NULL) {
+ goto bail;
+ }
+
+ ptr = (const unsigned char*) file->getDataPtr();
+
/*
* Experiment with madvise hint. When we want to uncompress a file,
* we pull some stuff out of the central dir entry and then hit a
@@ -507,17 +632,17 @@
* pair of system calls are negated by a reduction in page faults.
*/
if (compLen > kSequentialMin)
- mFileMap->advise(FileMap::SEQUENTIAL);
+ file->advise(FileMap::SEQUENTIAL);
if (method == kCompressStored) {
- memcpy(buffer, basePtr + offset, uncompLen);
+ memcpy(buffer, ptr, uncompLen);
} else {
- if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+ if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
goto bail;
}
if (compLen > kSequentialMin)
- mFileMap->advise(FileMap::NORMAL);
+ file->advise(FileMap::NORMAL);
result = true;
@@ -537,29 +662,34 @@
if (ent < 0)
return -1;
- const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
int method;
- long uncompLen, compLen;
+ size_t uncompLen, compLen;
off_t offset;
+ const unsigned char* ptr;
getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
- if (method == kCompressStored) {
- ssize_t actual;
+ const FileMap* file = createEntryFileMap(entry);
+ if (file == NULL) {
+ goto bail;
+ }
- actual = write(fd, basePtr + offset, uncompLen);
+ ptr = (const unsigned char*) file->getDataPtr();
+
+ if (method == kCompressStored) {
+ ssize_t actual = write(fd, ptr, uncompLen);
if (actual < 0) {
LOGE("Write failed: %s\n", strerror(errno));
goto bail;
- } else if (actual != uncompLen) {
- LOGE("Partial write during uncompress (%d of %ld)\n",
- (int)actual, uncompLen);
+ } else if ((size_t) actual != uncompLen) {
+ LOGE("Partial write during uncompress (%zd of %zd)\n",
+ actual, uncompLen);
goto bail;
} else {
LOGI("+++ successful write\n");
}
} else {
- if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+ if (!inflateBuffer(fd, ptr, uncompLen, compLen))
goto bail;
}
@@ -573,7 +703,7 @@
* Uncompress "deflate" data from one buffer to another.
*/
/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
- long uncompLen, long compLen)
+ size_t uncompLen, size_t compLen)
{
bool result = false;
z_stream zstream;
@@ -582,7 +712,7 @@
/*
* Initialize the zlib stream struct.
*/
- memset(&zstream, 0, sizeof(zstream));
+ memset(&zstream, 0, sizeof(zstream));
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
@@ -592,10 +722,10 @@
zstream.avail_out = uncompLen;
zstream.data_type = Z_UNKNOWN;
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
+ /*
+ * Use the undocumented "negative window bits" feature to tell zlib
+ * that there's no zlib header waiting for it.
+ */
zerr = inflateInit2(&zstream, -MAX_WBITS);
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
@@ -619,8 +749,8 @@
}
/* paranoia */
- if ((long) zstream.total_out != uncompLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+ if (zstream.total_out != uncompLen) {
+ LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
zstream.total_out, uncompLen);
goto z_bail;
}
@@ -638,10 +768,10 @@
* Uncompress "deflate" data from one buffer to an open file descriptor.
*/
/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
- long uncompLen, long compLen)
+ size_t uncompLen, size_t compLen)
{
bool result = false;
- const int kWriteBufSize = 32768;
+ const size_t kWriteBufSize = 32768;
unsigned char writeBuf[kWriteBufSize];
z_stream zstream;
int zerr;
@@ -649,7 +779,7 @@
/*
* Initialize the zlib stream struct.
*/
- memset(&zstream, 0, sizeof(zstream));
+ memset(&zstream, 0, sizeof(zstream));
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
@@ -659,10 +789,10 @@
zstream.avail_out = sizeof(writeBuf);
zstream.data_type = Z_UNKNOWN;
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
+ /*
+ * Use the undocumented "negative window bits" feature to tell zlib
+ * that there's no zlib header waiting for it.
+ */
zerr = inflateInit2(&zstream, -MAX_WBITS);
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
@@ -708,8 +838,8 @@
assert(zerr == Z_STREAM_END); /* other errors should've been caught */
/* paranoia */
- if ((long) zstream.total_out != uncompLen) {
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+ if (zstream.total_out != uncompLen) {
+ LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
zstream.total_out, uncompLen);
goto z_bail;
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 2e3eae0..b23dcde 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1382,7 +1382,11 @@
}
/**
- * Register a listener for audio focus updates.
+ * @hide
+ * Registers a listener to be called when audio focus changes. Calling this method is optional
+ * before calling {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, as it
+ * will register the listener as well if it wasn't registered already.
+ * @param l the listener to be notified of audio focus changes.
*/
public void registerAudioFocusListener(OnAudioFocusChangeListener l) {
synchronized(mFocusListenerLock) {
@@ -1394,16 +1398,12 @@
}
/**
- * TODO document for SDK
+ * @hide
+ * Causes the specified listener to not be called anymore when focus is gained or lost.
+ * @param l the listener to unregister.
*/
public void unregisterAudioFocusListener(OnAudioFocusChangeListener l) {
- // notify service to remove it from audio focus stack
- IAudioService service = getService();
- try {
- service.unregisterAudioFocusClient(getIdForAudioFocusListener(l));
- } catch (RemoteException e) {
- Log.e(TAG, "Can't call unregisterFocusClient() from AudioService due to "+e);
- }
+
// remove locally
synchronized(mFocusListenerLock) {
mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l));
@@ -1412,18 +1412,18 @@
/**
- * TODO document for SDK
+ * A failed focus change request.
*/
public static final int AUDIOFOCUS_REQUEST_FAILED = 0;
/**
- * TODO document for SDK
+ * A successful focus change request.
*/
public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;
/**
* Request audio focus.
- * Send a request to obtain the audio focus for a specific stream type
+ * Send a request to obtain the audio focus
* @param l the listener to be notified of audio focus changes
* @param streamType the main audio stream type affected by the focus request
* @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
@@ -1456,13 +1456,13 @@
/**
- * TODO document for SDK
- * Abandon audio focus.
+ * Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
+ * @param l the listener with which focus was requested.
* @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
*/
public int abandonAudioFocus(OnAudioFocusChangeListener l) {
int status = AUDIOFOCUS_REQUEST_FAILED;
- registerAudioFocusListener(l);
+ unregisterAudioFocusListener(l);
IAudioService service = getService();
try {
status = service.abandonAudioFocus(mAudioFocusDispatcher,
@@ -1477,7 +1477,7 @@
//====================================================================
// Remote Control
/**
- * TODO document for SDK
+ * Register a component to be the sole receiver of MEDIA_BUTTON intents.
* @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
* that will receive the media button intent. This broadcast receiver must be declared
* in the application manifest.
@@ -1493,7 +1493,9 @@
}
/**
- * TODO document for SDK
+ * Unregister the receiver of MEDIA_BUTTON intents.
+ * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
+ * that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
*/
public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
IAudioService service = getService();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index d55d0a5..5c278d9 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1930,6 +1930,8 @@
*/
private final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
+ private final static Object mAudioFocusLock = new Object();
+
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
@@ -2000,7 +2002,7 @@
*/
private void dumpFocusStack(PrintWriter pw) {
pw.println("\nAudio Focus stack entries:");
- synchronized(mFocusStack) {
+ synchronized(mAudioFocusLock) {
Iterator<FocusStackEntry> stackIterator = mFocusStack.iterator();
while(stackIterator.hasNext()) {
FocusStackEntry fse = stackIterator.next();
@@ -2091,7 +2093,7 @@
}
public void binderDied() {
- synchronized(mFocusStack) {
+ synchronized(mAudioFocusLock) {
Log.w(TAG, " AudioFocus audio focus client died");
removeFocusStackEntryForClient(mCb);
}
@@ -2117,11 +2119,11 @@
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
- if (!canReassignAudioFocus()) {
- return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
- }
+ synchronized(mAudioFocusLock) {
+ if (!canReassignAudioFocus()) {
+ return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+ }
- synchronized(mFocusStack) {
if (!mFocusStack.empty() && mFocusStack.peek().mClientId.equals(clientId)) {
// if focus is already owned by this client and the reason for acquiring the focus
// hasn't changed, don't do anything
@@ -2151,7 +2153,7 @@
// push focus requester at the top of the audio focus stack
mFocusStack.push(new FocusStackEntry(mainStreamType, focusChangeHint, false, fd, cb,
clientId));
- }//synchronized(mFocusStack)
+ }//synchronized(mAudioFocusLock)
// handle the potential premature death of the new holder of the focus
// (premature death == death before abandoning focus) for a client which is not the
@@ -2173,10 +2175,17 @@
/** @see AudioManager#abandonAudioFocus(IAudioFocusDispatcher) */
public int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId) {
Log.i(TAG, " AudioFocus abandonAudioFocus() from " + clientId);
-
- // this will take care of notifying the new focus owner if needed
- synchronized(mFocusStack) {
- removeFocusStackEntry(clientId, true);
+ try {
+ // this will take care of notifying the new focus owner if needed
+ synchronized(mAudioFocusLock) {
+ removeFocusStackEntry(clientId, true);
+ }
+ } catch (java.util.ConcurrentModificationException cme) {
+ // Catching this exception here is temporary. It is here just to prevent
+ // a crash seen when the "Silent" notification is played. This is believed to be fixed
+ // but this try catch block is left just to be safe.
+ Log.e(TAG, "FATAL EXCEPTION AudioFocus abandonAudioFocus() caused " + cme);
+ cme.printStackTrace();
}
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
@@ -2184,7 +2193,7 @@
public void unregisterAudioFocusClient(String clientId) {
- synchronized(mFocusStack) {
+ synchronized(mAudioFocusLock) {
removeFocusStackEntry(clientId, false);
}
}
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index e80ece6..013f8fc 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -869,12 +869,15 @@
values.put(MediaStore.Images.ImageColumns.DATA, "");
String [] pathSpec = new String[] {path + '%'};
try {
+ // These tables have DELETE_FILE triggers that delete the file from the
+ // sd card when deleting the database entry. We don't want to do this in
+ // this case, since it would cause those files to be removed if a .nomedia
+ // file was added after the fact, when in that case we only want the database
+ // entries to be removed.
mMediaProvider.update(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values,
MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
mMediaProvider.update(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values,
MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
- mMediaProvider.update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values,
- MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
} catch (RemoteException e) {
throw new RuntimeException();
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 475160e..f668caa 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -778,7 +778,12 @@
}
}
- mAudioSource->start();
+ status_t err = mAudioSource->start();
+
+ if (err != OK) {
+ mAudioSource.clear();
+ return err;
+ }
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_QCELP)) {
// For legacy reasons we're simply going to ignore the absence
// of an audio decoder for QCELP instead of aborting playback
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 038c3b3..3a1e3bc 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -40,6 +40,9 @@
virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) {
return NULL;
}
+ virtual status_t setBufferCount(int bufferCount) {
+ return INVALID_OPERATION;
+ }
virtual status_t registerBuffers(const BufferHeap &buffers) {
return OK;
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp
index 8e26c37e..f72a6cc 100644
--- a/media/libstagefright/HTTPDataSource.cpp
+++ b/media/libstagefright/HTTPDataSource.cpp
@@ -84,6 +84,7 @@
}
if (httpStatus >= 200 && httpStatus < 300) {
+ applyTimeoutResponse();
return OK;
}
@@ -133,6 +134,22 @@
return ERROR_IO;
}
+void HTTPDataSource::applyTimeoutResponse() {
+ string timeout;
+ if (mHttp->find_header_value("X-SocketTimeout", &timeout)) {
+ const char *s = timeout.c_str();
+ char *end;
+ long tmp = strtol(s, &end, 10);
+ if (end == s || *end != '\0') {
+ LOGW("Illegal X-SocketTimeout value given.");
+ return;
+ }
+
+ LOGI("overriding default timeout, new timeout is %ld seconds", tmp);
+ mHttp->setReceiveTimeout(tmp);
+ }
+}
+
HTTPDataSource::HTTPDataSource(
const char *uri, const KeyedVector<String8, String8> *headers) {
CHECK(!strncasecmp("http://", uri, 7));
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 6145ec2..9c99866 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -68,10 +68,7 @@
return UNKNOWN_ERROR;
}
- struct timeval tv;
- tv.tv_usec = 0;
- tv.tv_sec = 5;
- CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));
+ setReceiveTimeout(5); // Time out reads after 5 secs by default
mState = CONNECTING;
@@ -329,5 +326,17 @@
return true;
}
+void HTTPStream::setReceiveTimeout(int seconds) {
+ if (seconds < 0) {
+ // Disable the timeout.
+ seconds = 0;
+ }
+
+ struct timeval tv;
+ tv.tv_usec = 0;
+ tv.tv_sec = seconds;
+ CHECK_EQ(0, setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));
+}
+
} // namespace android
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 699b955..d0d1b14 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -94,6 +94,8 @@
size_t mCurrentPageSize;
size_t mNextLaceIndex;
+ off_t mFirstDataOffset;
+
vorbis_info mVi;
vorbis_comment mVc;
@@ -183,7 +185,8 @@
: mSource(source),
mOffset(0),
mCurrentPageSize(0),
- mNextLaceIndex(0) {
+ mNextLaceIndex(0),
+ mFirstDataOffset(-1) {
mCurrentPage.mNumSegments = 0;
}
@@ -222,6 +225,12 @@
}
status_t MyVorbisExtractor::seekToOffset(off_t offset) {
+ if (mFirstDataOffset >= 0 && offset < mFirstDataOffset) {
+ // Once we know where the actual audio data starts (past the headers)
+ // don't ever seek to anywhere before that.
+ offset = mFirstDataOffset;
+ }
+
off_t pageOffset;
status_t err = findNextPage(offset, &pageOffset);
@@ -438,6 +447,8 @@
verifyHeader(packet, 5);
packet->release();
packet = NULL;
+
+ mFirstDataOffset = mOffset + mCurrentPageSize;
}
void MyVorbisExtractor::verifyHeader(
diff --git a/media/libstagefright/codecs/aacdec/AACDecoder.cpp b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
index ae23691..2bc4448 100644
--- a/media/libstagefright/codecs/aacdec/AACDecoder.cpp
+++ b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
@@ -90,8 +90,10 @@
mConfig->pOutputBuffer_plus = NULL;
mConfig->repositionFlag = false;
- CHECK_EQ(PVMP4AudioDecoderConfig(mConfig, mDecoderBuf),
- MP4AUDEC_SUCCESS);
+ if (PVMP4AudioDecoderConfig(mConfig, mDecoderBuf)
+ != MP4AUDEC_SUCCESS) {
+ return ERROR_UNSUPPORTED;
+ }
}
mSource->start();
diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
index 5485f25..df3f16a 100644
--- a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
@@ -173,18 +173,19 @@
pack.granulepos = 0;
pack.packetno = 0;
+ int numFrames = 0;
+
int err = vorbis_dsp_synthesis(mState, &pack, 1);
if (err != 0) {
LOGW("vorbis_dsp_synthesis returned %d", err);
- return 0;
- }
+ } else {
+ numFrames = vorbis_dsp_pcmout(
+ mState, (int16_t *)out->data(), kMaxNumSamplesPerBuffer);
- int numFrames = vorbis_dsp_pcmout(
- mState, (int16_t *)out->data(), kMaxNumSamplesPerBuffer);
-
- if (numFrames < 0) {
- LOGE("vorbis_dsp_pcmout returned %d", numFrames);
- return 0;
+ if (numFrames < 0) {
+ LOGE("vorbis_dsp_pcmout returned %d", numFrames);
+ numFrames = 0;
+ }
}
out->set_range(0, numFrames * sizeof(int16_t) * mNumChannels);
@@ -203,6 +204,7 @@
CHECK(seekTimeUs >= 0);
mNumFramesOutput = 0;
+ vorbis_dsp_restart(mState);
} else {
seekTimeUs = -1;
}
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
index 5d638f3..35b0865 100644
--- a/media/libstagefright/include/HTTPStream.h
+++ b/media/libstagefright/include/HTTPStream.h
@@ -52,6 +52,9 @@
bool find_header_value(
const string &key, string *value) const;
+ // Pass a negative value to disable the timeout.
+ void setReceiveTimeout(int seconds);
+
private:
enum State {
READY,
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 6cb146c..8abd6499 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -37,6 +37,10 @@
LOCAL_CFLAGS += -fstrict-aliasing
endif
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+ LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
ifneq ($(TARGET_SIMULATOR),true)
# we need to access the private Bionic header <bionic_tls.h>
# on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 9407bd5..d67612e 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -1515,7 +1515,7 @@
ogles_error(c, GL_INVALID_VALUE);
return;
}
- if (x<0 || x<0) {
+ if (x<0 || y<0) {
ogles_error(c, GL_INVALID_VALUE);
return;
}
diff --git a/policy/com/android/internal/policy/impl/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java
index 5592b6d..20d9f26 100644
--- a/policy/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/com/android/internal/policy/impl/PhoneWindow.java
@@ -21,13 +21,6 @@
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.android.internal.view.menu.MenuBuilder;
-import com.android.internal.view.menu.MenuDialogHelper;
-import com.android.internal.view.menu.MenuView;
-import com.android.internal.view.menu.SubMenuBuilder;
-
import android.app.KeyguardManager;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
@@ -51,6 +44,7 @@
import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
+import android.view.ActionBarView;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyCharacterMap;
@@ -75,6 +69,12 @@
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.internal.view.menu.ContextMenuBuilder;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuDialogHelper;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
+
/**
* Android-specific Window.
* <p>
@@ -105,6 +105,8 @@
private LayoutInflater mLayoutInflater;
private TextView mTitleView;
+
+ private ActionBarView mActionBar;
private DrawableFeatureState[] mDrawables;
@@ -258,6 +260,8 @@
public void setTitle(CharSequence title) {
if (mTitleView != null) {
mTitleView.setText(title);
+ } else if (mActionBar != null) {
+ mActionBar.setTitle(title);
}
mTitle = title;
}
@@ -2067,6 +2071,9 @@
if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
+ } else if (a.getBoolean(com.android.internal.R.styleable.Window_windowActionBar, false)) {
+ // Don't allow an action bar if there is no title.
+ requestFeature(FEATURE_ACTION_BAR);
}
if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {
@@ -2150,6 +2157,8 @@
// If the window is floating, we need a dialog layout
if (mIsFloating) {
layoutResource = com.android.internal.R.layout.dialog_title;
+ } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
+ layoutResource = com.android.internal.R.layout.screen_action_bar;
} else {
layoutResource = com.android.internal.R.layout.screen_title;
}
@@ -2234,6 +2243,13 @@
} else {
mTitleView.setText(mTitle);
}
+ } else {
+ mActionBar = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ if (mActionBar != null) {
+ if (mActionBar.getTitle() == null) {
+ mActionBar.setTitle(mTitle);
+ }
+ }
}
}
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 5bf66e4..90c456c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -472,8 +472,10 @@
mContext.getContentResolver(),
Settings.Secure.ENABLED_INPUT_METHODS);
Slog.i(TAG, "Enabled input methods: " + enabledStr);
- if (enabledStr == null) {
- Slog.i(TAG, "Enabled input methods has not been set, enabling all");
+ final String defaultIme = Settings.Secure.getString(mContext
+ .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ if (enabledStr == null || TextUtils.isEmpty(defaultIme)) {
+ Slog.i(TAG, "Enabled input methods or default IME has not been set, enabling all");
InputMethodInfo defIm = null;
StringBuilder sb = new StringBuilder(256);
final int N = mMethodList.size();
@@ -1483,7 +1485,7 @@
String defaultIme = Settings.Secure.getString(mContext
.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- if (!map.containsKey(defaultIme)) {
+ if (!TextUtils.isEmpty(defaultIme) && !map.containsKey(defaultIme)) {
if (chooseNewDefaultIMELocked()) {
updateFromSettingsLocked();
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index b92480f..be03ab5 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1646,7 +1646,7 @@
synchronized (mLock) {
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderInterface provider = mProviders.get(i);
- if (provider.isEnabled() && provider.requiresNetwork()) {
+ if (provider.requiresNetwork()) {
provider.updateNetworkState(mNetworkState, info);
}
}
diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java
index 0b1a03b..52d2381 100644
--- a/services/java/com/android/server/NotificationPlayer.java
+++ b/services/java/com/android/server/NotificationPlayer.java
@@ -88,12 +88,15 @@
player.setDataSource(mCmd.context, mCmd.uri);
player.setLooping(mCmd.looping);
player.prepare();
- if (mCmd.looping) {
- audioManager.requestAudioFocus(null, mCmd.stream,
- AudioManager.AUDIOFOCUS_GAIN);
- } else {
- audioManager.requestAudioFocus(null, mCmd.stream,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
+ if ((mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null)
+ && (mCmd.uri.getEncodedPath().length() > 0)) {
+ if (mCmd.looping) {
+ audioManager.requestAudioFocus(null, mCmd.stream,
+ AudioManager.AUDIOFOCUS_GAIN);
+ } else {
+ audioManager.requestAudioFocus(null, mCmd.stream,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
+ }
}
player.setOnCompletionListener(NotificationPlayer.this);
player.start();
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index caa015a..6966400 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -6528,18 +6528,30 @@
case RawInputEvent.CLASS_KEYBOARD:
KeyEvent ke = (KeyEvent)ev.event;
if (ke.isDown()) {
- lastKey = ke;
- downTime = curTime;
- keyRepeatCount = 0;
lastKeyTime = curTime;
- nextKeyTime = lastKeyTime
- + ViewConfiguration.getLongPressTimeout();
- if (DEBUG_INPUT) Slog.v(
- TAG, "Received key down: first repeat @ "
- + nextKeyTime);
+ if (lastKey != null &&
+ ke.getKeyCode() == lastKey.getKeyCode()) {
+ keyRepeatCount++;
+ // Arbitrary long timeout to block
+ // repeating here since we know that
+ // the device driver takes care of it.
+ nextKeyTime = lastKeyTime + LONG_WAIT;
+ if (DEBUG_INPUT) Slog.v(
+ TAG, "Received repeated key down");
+ } else {
+ downTime = curTime;
+ keyRepeatCount = 0;
+ nextKeyTime = lastKeyTime
+ + ViewConfiguration.getLongPressTimeout();
+ if (DEBUG_INPUT) Slog.v(
+ TAG, "Received key down: first repeat @ "
+ + nextKeyTime);
+ }
+ lastKey = ke;
} else {
lastKey = null;
downTime = 0;
+ keyRepeatCount = 0;
// Arbitrary long timeout.
lastKeyTime = curTime;
nextKeyTime = curTime + LONG_WAIT;
@@ -6547,7 +6559,12 @@
TAG, "Received key up: ignore repeat @ "
+ nextKeyTime);
}
- dispatchKey((KeyEvent)ev.event, 0, 0);
+ if (keyRepeatCount > 0) {
+ dispatchKey(KeyEvent.changeTimeRepeat(ke,
+ ke.getEventTime(), keyRepeatCount), 0, 0);
+ } else {
+ dispatchKey(ke, 0, 0);
+ }
mQueue.recycleEvent(ev);
break;
case RawInputEvent.CLASS_TOUCHSCREEN:
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 948d292..022eccf 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7858,18 +7858,18 @@
r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
}
cpr.clients.add(r);
- } else {
- cpr.externals++;
- }
-
- if (cpr.app != null) {
- if (r.setAdj >= VISIBLE_APP_ADJ) {
+ if (cpr.app != null && r.setAdj >= VISIBLE_APP_ADJ) {
// If this is a visible app accessing the provider,
// make sure to count it as being accessed and thus
// back up on the LRU list. This is good because
// content providers are often expensive to start.
updateLruProcessLocked(cpr.app, false, true);
}
+ } else {
+ cpr.externals++;
+ }
+
+ if (cpr.app != null) {
updateOomAdjLocked(cpr.app);
}
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 1816181..35ccfe8 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -954,7 +954,9 @@
&& ((mServiceState.getRadioTechnology()
== ServiceState.RADIO_TECHNOLOGY_EVDO_0)
|| (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_A)));
+ == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
+ || (mServiceState.getRadioTechnology()
+ == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
}
private boolean hasService() {
@@ -1070,7 +1072,6 @@
}
private final void updateDataNetType(int net) {
-
switch (net) {
case TelephonyManager.NETWORK_TYPE_EDGE:
mDataIconList = sDataNetType_e;
@@ -1096,6 +1097,7 @@
break;
case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
mDataIconList = sDataNetType_3g;
break;
default:
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 6c66559..1f00885 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -89,6 +89,8 @@
public static final int RADIO_TECHNOLOGY_HSUPA = 10;
/** @hide */
public static final int RADIO_TECHNOLOGY_HSPA = 11;
+ /** @hide */
+ public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
/**
* Available registration states for GSM, UMTS and CDMA.
@@ -379,7 +381,6 @@
@Override
public String toString() {
String radioTechnology = new String("Error in radioTechnology");
-
switch(this.mRadioTechnology) {
case 0:
radioTechnology = "Unknown";
@@ -417,6 +418,9 @@
case 11:
radioTechnology = "HSPA";
break;
+ case 12:
+ radioTechnology = "EvDo rev. B";
+ break;
default:
Log.w(LOG_TAG, "mRadioTechnology variable out of range.");
break;
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 2a969bb..953696b 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -395,4 +395,6 @@
static public final int RESULT_ERROR_NO_SERVICE = 4;
/** Failed because we reached the sending queue limit. {@hide} */
static public final int RESULT_ERROR_LIMIT_EXCEEDED = 5;
+ /** Failed because FDN is enabled. {@hide} */
+ static public final int RESULT_ERROR_FDN_CHECK_FAILURE = 6;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f018d107..ab63017 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -391,6 +391,9 @@
public static final int NETWORK_TYPE_HSPA = 10;
/** Current network is iDen */
public static final int NETWORK_TYPE_IDEN = 11;
+ /** Current network is EVDO revision B*/
+ public static final int NETWORK_TYPE_EVDO_B = 12;
+
/**
* Returns a constant indicating the radio technology (network type)
@@ -407,6 +410,7 @@
* @see #NETWORK_TYPE_CDMA
* @see #NETWORK_TYPE_EVDO_0
* @see #NETWORK_TYPE_EVDO_A
+ * @see #NETWORK_TYPE_EVDO_B
* @see #NETWORK_TYPE_1xRTT
*/
public int getNetworkType() {
@@ -454,6 +458,8 @@
return "CDMA - EvDo rev. 0";
case NETWORK_TYPE_EVDO_A:
return "CDMA - EvDo rev. A";
+ case NETWORK_TYPE_EVDO_B:
+ return "CDMA - EvDo rev. B";
case NETWORK_TYPE_1xRTT:
return "CDMA - 1xRTT";
default:
diff --git a/telephony/java/com/android/internal/telephony/CommandException.java b/telephony/java/com/android/internal/telephony/CommandException.java
index eb0a440..94c544e 100644
--- a/telephony/java/com/android/internal/telephony/CommandException.java
+++ b/telephony/java/com/android/internal/telephony/CommandException.java
@@ -37,6 +37,10 @@
OP_NOT_ALLOWED_DURING_VOICE_CALL,
OP_NOT_ALLOWED_BEFORE_REG_NW,
SMS_FAIL_RETRY,
+ SIM_ABSENT,
+ SUBSCRIPTION_NOT_AVAILABLE,
+ MODE_NOT_SUPPORTED,
+ FDN_CHECK_FAILURE,
ILLEGAL_SIM_OR_ME,
}
@@ -69,6 +73,14 @@
return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW);
case RILConstants.SMS_SEND_FAIL_RETRY:
return new CommandException(Error.SMS_FAIL_RETRY);
+ case RILConstants.SIM_ABSENT:
+ return new CommandException(Error.SIM_ABSENT);
+ case RILConstants.SUBSCRIPTION_NOT_AVAILABLE:
+ return new CommandException(Error.SUBSCRIPTION_NOT_AVAILABLE);
+ case RILConstants.MODE_NOT_SUPPORTED:
+ return new CommandException(Error.MODE_NOT_SUPPORTED);
+ case RILConstants.FDN_CHECK_FAILURE:
+ return new CommandException(Error.FDN_CHECK_FAILURE);
case RILConstants.ILLEGAL_SIM_OR_ME:
return new CommandException(Error.ILLEGAL_SIM_OR_ME);
default:
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 9055203..5f27e3f 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -664,6 +664,19 @@
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the orignal value of result.obj
+ * ar.result is null on success and failure
+ *
+ * CLIR_DEFAULT == on "use subscription default value"
+ * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
+ * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
+ */
+ void dial(String address, int clirMode, UUSInfo uusInfo, Message result);
+
+ /**
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * ar.userObject contains the orignal value of result.obj
* ar.result is String containing IMSI on success
*/
void getIMSI(Message result);
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index 37e8a99..0bcb63a 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -50,6 +50,7 @@
CS_RESTRICTED, /* call was blocked by restricted all voice access */
CS_RESTRICTED_NORMAL, /* call was blocked by restricted normal voice access */
CS_RESTRICTED_EMERGENCY, /* call was blocked by restricted emergency voice access */
+ UNOBTAINABLE_NUMBER, /* Unassigned number (3GPP TS 24.008 table 10.5.123) */
CDMA_LOCKED_UNTIL_POWER_CYCLE, /* MS is locked until next power cycle */
CDMA_DROP,
CDMA_INTERCEPT, /* INTERCEPT order received, MS state idle entered */
@@ -273,6 +274,13 @@
public abstract int getNumberPresentation();
/**
+ * Returns the User to User Signaling (UUS) information associated with
+ * incoming and waiting calls
+ * @return UUSInfo containing the UUS userdata.
+ */
+ public abstract UUSInfo getUUSInfo();
+
+ /**
* Build a human representation of a connection instance, suitable for debugging.
* Don't log personal stuff unless in debug mode.
* @return a string representing the internal state of this connection.
diff --git a/telephony/java/com/android/internal/telephony/DriverCall.java b/telephony/java/com/android/internal/telephony/DriverCall.java
index 66f6b9c..663c284 100644
--- a/telephony/java/com/android/internal/telephony/DriverCall.java
+++ b/telephony/java/com/android/internal/telephony/DriverCall.java
@@ -49,6 +49,7 @@
public int numberPresentation;
public String name;
public int namePresentation;
+ public UUSInfo uusInfo;
/** returns null on error */
static DriverCall
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 7179bef..f14ab70 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -789,6 +789,19 @@
Connection dial(String dialString) throws CallStateException;
/**
+ * Initiate a new voice connection with supplementary User to User
+ * Information. This happens asynchronously, so you cannot assume the audio
+ * path is connected (or a call index has been assigned) until
+ * PhoneStateChanged notification has occurred.
+ *
+ * @exception CallStateException if a new outgoing call is not currently
+ * possible because no more call slots exist or a call exists
+ * that is dialing, alerting, ringing, or waiting. Other
+ * errors are handled asynchronously.
+ */
+ Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException;
+
+ /**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
*
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 6d3798e..e1511e6 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -423,6 +423,10 @@
return mActivePhone.dial(dialString);
}
+ public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
+ return mActivePhone.dial(dialString, uusInfo);
+ }
+
public boolean handlePinMmi(String dialString) {
return mActivePhone.handlePinMmi(dialString);
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index b942ad7..5bd9e39 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -795,12 +795,26 @@
public void
dial (String address, int clirMode, Message result) {
+ dial(address, clirMode, null, result);
+ }
+
+ public void
+ dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);
rr.mp.writeString(address);
rr.mp.writeInt(clirMode);
rr.mp.writeInt(0); // UUS information is absent
+ if (uusInfo == null) {
+ rr.mp.writeInt(0); // UUS information is absent
+ } else {
+ rr.mp.writeInt(1); // UUS information is present
+ rr.mp.writeInt(uusInfo.getType());
+ rr.mp.writeInt(uusInfo.getDcs());
+ rr.mp.writeByteArray(uusInfo.getUserData());
+ }
+
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
@@ -2836,10 +2850,21 @@
dc.namePresentation = p.readInt();
int uusInfoPresent = p.readInt();
if (uusInfoPresent == 1) {
- // TODO: Copy the data to dc to forward to the apps.
- p.readInt();
- p.readInt();
- p.createByteArray();
+ dc.uusInfo = new UUSInfo();
+ dc.uusInfo.setType(p.readInt());
+ dc.uusInfo.setDcs(p.readInt());
+ byte[] userData = p.createByteArray();
+ dc.uusInfo.setUserData(userData);
+ Log
+ .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+ dc.uusInfo.getType(), dc.uusInfo.getDcs(),
+ dc.uusInfo.getUserData().length));
+ Log.v(LOG_TAG, "Incoming UUS : data (string)="
+ + new String(dc.uusInfo.getUserData()));
+ Log.v(LOG_TAG, "Incoming UUS : data (hex): "
+ + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
+ } else {
+ Log.v(LOG_TAG, "Incoming UUS : NOT present!");
}
// Make sure there's a leading + on addresses with a TOA of 145
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 01f4ab2..71a80e0 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -45,6 +45,11 @@
int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to
network */
int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */
+ int SIM_ABSENT = 11; /* ICC card is absent */
+ int SUBSCRIPTION_NOT_AVAILABLE = 12; /* fail to find CDMA subscription from specified
+ location */
+ int MODE_NOT_SUPPORTED = 13; /* HW does not support preferred network type */
+ int FDN_CHECK_FAILURE = 14; /* send operation barred error when FDN is enabled */
int ILLEGAL_SIM_OR_ME = 15; /* network selection failure due
to wrong SIM/ME and no
retries needed */
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index fb58e14..9e17eb1 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -62,6 +62,7 @@
import static android.telephony.SmsManager.RESULT_ERROR_NULL_PDU;
import static android.telephony.SmsManager.RESULT_ERROR_RADIO_OFF;
import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
+import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
public abstract class SMSDispatcher extends Handler {
@@ -500,13 +501,20 @@
Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker);
sendMessageDelayed(retryMsg, SEND_RETRY_DELAY);
} else if (tracker.mSentIntent != null) {
+ int error = RESULT_ERROR_GENERIC_FAILURE;
+
+ if (((CommandException)(ar.exception)).getCommandError()
+ == CommandException.Error.FDN_CHECK_FAILURE) {
+ error = RESULT_ERROR_FDN_CHECK_FAILURE;
+ }
// Done retrying; return an error to the app.
try {
Intent fillIn = new Intent();
if (ar.result != null) {
fillIn.putExtra("errorCode", ((SmsResponse)ar.result).errorCode);
}
- tracker.mSentIntent.send(mContext, RESULT_ERROR_GENERIC_FAILURE, fillIn);
+ tracker.mSentIntent.send(mContext, error, fillIn);
+
} catch (CanceledException ex) {}
}
}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 7383649..706f260 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -44,6 +44,7 @@
protected static final int DATA_ACCESS_HSDPA = 9;
protected static final int DATA_ACCESS_HSUPA = 10;
protected static final int DATA_ACCESS_HSPA = 11;
+ protected static final int DATA_ACCESS_CDMA_EvDo_B = 12;
protected CommandsInterface cm;
diff --git a/telephony/java/com/android/internal/telephony/UUSInfo.java b/telephony/java/com/android/internal/telephony/UUSInfo.java
new file mode 100644
index 0000000..801b845
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/UUSInfo.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+public class UUSInfo {
+
+ /*
+ * User-to-User signaling Info activation types derived from 3GPP 23.087
+ * v8.0
+ */
+
+ public static final int UUS_TYPE1_IMPLICIT = 0;
+
+ public static final int UUS_TYPE1_REQUIRED = 1;
+
+ public static final int UUS_TYPE1_NOT_REQUIRED = 2;
+
+ public static final int UUS_TYPE2_REQUIRED = 3;
+
+ public static final int UUS_TYPE2_NOT_REQUIRED = 4;
+
+ public static final int UUS_TYPE3_REQUIRED = 5;
+
+ public static final int UUS_TYPE3_NOT_REQUIRED = 6;
+
+ /*
+ * User-to-User Signaling Information data coding schemes. Possible values
+ * for Octet 3 (Protocol Discriminator field) in the UUIE. The values have
+ * been specified in section 10.5.4.25 of 3GPP TS 24.008
+ */
+
+ public static final int UUS_DCS_USP = 0; /* User specified protocol */
+
+ public static final int UUS_DCS_OSIHLP = 1; /* OSI higher layer protocol */
+
+ public static final int UUS_DCS_X244 = 2; /* X.244 */
+
+ public static final int UUS_DCS_RMCF = 3; /*
+ * Reserved for system management
+ * convergence function
+ */
+
+ public static final int UUS_DCS_IA5c = 4; /* IA5 characters */
+
+ private int uusType;
+
+ private int uusDcs;
+
+ private byte[] uusData;
+
+ public UUSInfo() {
+ this.uusType = UUS_TYPE1_IMPLICIT;
+ this.uusDcs = UUS_DCS_IA5c;
+ this.uusData = null;
+ }
+
+ public UUSInfo(int uusType, int uusDcs, byte[] uusData) {
+ this.uusType = uusType;
+ this.uusDcs = uusDcs;
+ this.uusData = uusData;
+ }
+
+ public int getDcs() {
+ return uusDcs;
+ }
+
+ public void setDcs(int uusDcs) {
+ this.uusDcs = uusDcs;
+ }
+
+ public int getType() {
+ return uusType;
+ }
+
+ public void setType(int uusType) {
+ this.uusType = uusType;
+ }
+
+ public byte[] getUserData() {
+ return uusData;
+ }
+
+ public void setUserData(byte[] uusData) {
+ this.uusData = uusData;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index d4b807c..0c591e4 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -62,6 +62,7 @@
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.UUSInfo;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
@@ -348,6 +349,10 @@
return mCT.dial(newDialString);
}
+ public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {
+ throw new CallStateException("Sending UUS information NOT supported in CDMA!");
+ }
+
public SignalStrength getSignalStrength() {
return mSST.mSignalStrength;
}
@@ -1444,5 +1449,4 @@
}
return false;
}
-
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 188145b..fbe455e 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -945,4 +945,10 @@
public int getNumberPresentation() {
return numberPresentation;
}
+
+ @Override
+ public UUSInfo getUUSInfo() {
+ // UUS information not supported in CDMA
+ return null;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 39fe007..6c71584 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -945,6 +945,9 @@
case DATA_ACCESS_CDMA_EvDo_A:
ret = "CDMA - EvDo rev. A";
break;
+ case DATA_ACCESS_CDMA_EvDo_B:
+ ret = "CDMA - EvDo rev. B";
+ break;
default:
if (DBG) {
Log.e(LOG_TAG, "Wrong network. Can not return a string.");
@@ -1237,6 +1240,7 @@
case 6: // RADIO_TECHNOLOGY_1xRTT
case 7: // RADIO_TECHNOLOGY_EVDO_0
case 8: // RADIO_TECHNOLOGY_EVDO_A
+ case 12: // RADIO_TECHNOLOGY_EVDO_B
retVal = ServiceState.STATE_IN_SERVICE;
break;
default:
diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
index e7fbf6b..af2ad48 100644
--- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
+++ b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java
@@ -25,6 +25,9 @@
*
*/
public interface CallFailCause {
+ // Unassigned/Unobtainable number
+ static final int UNOBTAINABLE_NUMBER = 1;
+
static final int NORMAL_CLEARING = 16;
// Busy Tone
static final int USER_BUSY = 17;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
old mode 100755
new mode 100644
index 2bb7968..c7b1e5c
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -67,6 +67,7 @@
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.gsm.stk.StkService;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.IccVmNotSupportedException;
@@ -711,7 +712,12 @@
}
public Connection
- dial (String dialString) throws CallStateException {
+ dial(String dialString) throws CallStateException {
+ return dial(dialString, null);
+ }
+
+ public Connection
+ dial (String dialString, UUSInfo uusInfo) throws CallStateException {
// Need to make sure dialString gets parsed properly
String newDialString = PhoneNumberUtils.stripSeparators(dialString);
@@ -727,9 +733,9 @@
"dialing w/ mmi '" + mmi + "'...");
if (mmi == null) {
- return mCT.dial(newDialString);
+ return mCT.dial(newDialString, uusInfo);
} else if (mmi.isTemporaryModeCLIR()) {
- return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode());
+ return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode(), uusInfo);
} else {
mPendingMMIs.add(mmi);
mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 87530e4..22fc13e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -37,6 +37,7 @@
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.GSMPhone;
import com.android.internal.telephony.gsm.GsmCall;
@@ -167,7 +168,7 @@
* clirMode is one of the CLIR_ constants
*/
Connection
- dial (String dialString, int clirMode) throws CallStateException {
+ dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
// note that this triggers call state changed notif
clearDisconnected();
@@ -213,7 +214,7 @@
// Always unmute when initiating a new call
setMute(false);
- cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());
+ cm.dial(pendingMO.address, clirMode, uusInfo, obtainCompleteMessage());
}
updatePhoneState();
@@ -222,10 +223,19 @@
return pendingMO;
}
+ Connection
+ dial(String dialString) throws CallStateException {
+ return dial(dialString, CommandsInterface.CLIR_DEFAULT, null);
+ }
Connection
- dial (String dialString) throws CallStateException {
- return dial(dialString, CommandsInterface.CLIR_DEFAULT);
+ dial(String dialString, UUSInfo uusInfo) throws CallStateException {
+ return dial(dialString, CommandsInterface.CLIR_DEFAULT, uusInfo);
+ }
+
+ Connection
+ dial(String dialString, int clirMode) throws CallStateException {
+ return dial(dialString, clirMode, null);
}
void
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 4788a01..7dc2504 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -73,6 +73,7 @@
DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED;
PostDialState postDialState = PostDialState.NOT_STARTED;
int numberPresentation = Connection.PRESENTATION_ALLOWED;
+ UUSInfo uusInfo;
Handler h;
@@ -126,6 +127,7 @@
isIncoming = dc.isMT;
createTime = System.currentTimeMillis();
numberPresentation = dc.numberPresentation;
+ uusInfo = dc.uusInfo;
this.index = index;
@@ -356,6 +358,9 @@
case CallFailCause.FDN_BLOCKED:
return DisconnectCause.FDN_BLOCKED;
+ case CallFailCause.UNOBTAINABLE_NUMBER:
+ return DisconnectCause.UNOBTAINABLE_NUMBER;
+
case CallFailCause.ERROR_UNSPECIFIED:
case CallFailCause.NORMAL_CLEARING:
default:
@@ -728,4 +733,9 @@
public int getNumberPresentation() {
return numberPresentation;
}
+
+ @Override
+ public UUSInfo getUUSInfo() {
+ return uusInfo;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index bcbd127..cacf057 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -832,8 +832,7 @@
if (ar.exception != null) {
state = State.FAILED;
- message = context.getText(
- com.android.internal.R.string.mmiError);
+ message = getErrorMessage(ar);
phone.onMMIDone(this);
}
@@ -852,6 +851,19 @@
}
//***** Private instance methods
+ private CharSequence getErrorMessage(AsyncResult ar) {
+
+ if (ar.exception instanceof CommandException) {
+ CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
+ if (err == CommandException.Error.FDN_CHECK_FAILURE) {
+ Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
+ return context.getText(com.android.internal.R.string.mmiFdnError);
+ }
+ }
+
+ return context.getText(com.android.internal.R.string.mmiError);
+ }
+
private CharSequence getScString() {
if (sc != null) {
if (isServiceCodeCallBarring(sc)) {
@@ -904,6 +916,9 @@
sb.append("\n");
sb.append(context.getText(
com.android.internal.R.string.needPuk2));
+ } else if (err == CommandException.Error.FDN_CHECK_FAILURE) {
+ Log.i(LOG_TAG, "FDN_CHECK_FAILURE");
+ sb.append(context.getText(com.android.internal.R.string.mmiFdnError));
} else {
sb.append(context.getText(
com.android.internal.R.string.mmiError));
@@ -953,7 +968,7 @@
if (ar.exception != null) {
state = State.FAILED;
- sb.append(context.getText(com.android.internal.R.string.mmiError));
+ sb.append(getErrorMessage(ar));
} else {
int clirArgs[];
@@ -1123,7 +1138,7 @@
if (ar.exception != null) {
state = State.FAILED;
- sb.append(context.getText(com.android.internal.R.string.mmiError));
+ sb.append(getErrorMessage(ar));
} else {
CallForwardInfo infos[];
@@ -1175,7 +1190,7 @@
if (ar.exception != null) {
state = State.FAILED;
- sb.append(context.getText(com.android.internal.R.string.mmiError));
+ sb.append(getErrorMessage(ar));
} else {
int[] ints = (int[])ar.result;
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 3675e78..fdcf78d 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -27,6 +27,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.UUSInfo;
import com.android.internal.telephony.gsm.CallFailCause;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
@@ -494,6 +495,23 @@
* retMsg.obj = AsyncResult ar
* ar.exception carries exception on failure
* ar.userObject contains the original value of result.obj
+ * ar.result is null on success and failure
+ *
+ * CLIR_DEFAULT == on "use subscription default value"
+ * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation)
+ * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation)
+ */
+ public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
+ simulatedCallState.onDial(address);
+
+ resultSuccess(result, null);
+ }
+
+ /**
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * ar.userObject contains the original value of result.obj
* ar.result is String containing IMSI on success
*/
public void getIMSI(Message result) {
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 962e96c..6d81b71 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -20,7 +20,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := core framework
+LOCAL_JAVA_LIBRARIES := core core-junit framework
LOCAL_MODULE:= android.test.runner
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index 0257a5e..41e0b2e 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -73,6 +73,7 @@
static final String[] ignoreTestList = {
"editing/selection/move-left-right.html", // Causes DumpRenderTree to hang
+ "fast/js/excessive-comma-usage.html", // Tests huge initializer list, causes OOM.
"fast/js/regexp-charclass-crash.html", // RegExp is too large, causing OOM
"fast/regex/test1.html", // Causes DumpRenderTree to hang with V8
"fast/regex/slow.html" // Causes DumpRenderTree to hang with V8
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java
index 50e2009..bc77e04 100755
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/ImfBaseTestCase.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
@@ -38,7 +39,7 @@
public final long WAIT_FOR_IME = 5000;
/*
- * Unfortunately there is now way for us to know how tall the IME is,
+ * Unfortunately there is now way for us to know how tall the IME is,
* so we have to hard code a minimum and maximum value.
*/
public final int IME_MIN_HEIGHT = 150;
@@ -48,20 +49,23 @@
protected T mTargetActivity;
protected boolean mExpectAutoPop;
private Class<T> mTargetActivityClass;
-
+
public ImfBaseTestCase(Class<T> activityClass) {
mTargetActivityClass = activityClass;
}
-
+
@Override
public void setUp() throws Exception {
super.setUp();
final String packageName = getInstrumentation().getTargetContext().getPackageName();
- mTargetActivity = launchActivity(packageName, mTargetActivityClass, null);
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ mTargetActivity = launchActivityWithIntent(packageName, mTargetActivityClass, intent);
// expect ime to auto pop up if device has no hard keyboard
- mExpectAutoPop = mTargetActivity.getResources().getConfiguration().hardKeyboardHidden ==
- Configuration.HARDKEYBOARDHIDDEN_YES;
-
+ int keyboardType = mTargetActivity.getResources().getConfiguration().keyboard;
+ mExpectAutoPop = (keyboardType == Configuration.KEYBOARD_NOKEYS ||
+ keyboardType == Configuration.KEYBOARD_UNDEFINED);
+
mImm = InputMethodManager.getInstance(mTargetActivity);
KeyguardManager keyguardManager =
@@ -115,26 +119,26 @@
assertFalse(destructiveCheckImeUp(rootView, servedView));
}
}
-
+
public boolean destructiveCheckImeUp(View rootView, View servedView) {
int origHeight;
int newHeight;
-
+
origHeight = rootView.getHeight();
-
+
// Tell the keyboard to go away.
mImm.hideSoftInputFromWindow(servedView.getWindowToken(), 0);
-
+
// Give it five seconds to adjust
newHeight = rootView.getHeight();
long timeoutTime = SystemClock.uptimeMillis() + WAIT_FOR_IME;
while (Math.abs(newHeight - origHeight) < IME_MIN_HEIGHT && SystemClock.uptimeMillis() < timeoutTime) {
newHeight = rootView.getHeight();
}
-
+
return (Math.abs(origHeight - newHeight) >= IME_MIN_HEIGHT);
}
-
+
void pause(int millis) {
try {
Thread.sleep(millis);