Merge change 23646 into eclair
* changes:
Immediately destroy BluetoothSocket's on close().
diff --git a/api/4.xml b/api/4.xml
index 49f5271..bca9816 100644
--- a/api/4.xml
+++ b/api/4.xml
@@ -4123,6 +4123,17 @@
visibility="public"
>
</field>
+<field name="includeInGlobalSearch"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843374"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="indeterminate"
type="int"
transient="false"
@@ -6191,6 +6202,17 @@
visibility="public"
>
</field>
+<field name="queryAfterZeroResults"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843394"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="radioButtonStyle"
type="int"
transient="false"
@@ -6686,6 +6708,17 @@
visibility="public"
>
</field>
+<field name="searchSettingsDescription"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843402"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="searchSuggestAuthority"
type="int"
transient="false"
@@ -6741,6 +6774,17 @@
visibility="public"
>
</field>
+<field name="searchSuggestThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843373"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="secondaryProgress"
type="int"
transient="false"
@@ -21158,6 +21202,17 @@
visibility="public"
>
</field>
+<field name="INTENT_ACTION_WEB_SEARCH_SETTINGS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.search.action.WEB_SEARCH_SETTINGS""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="MENU_KEY"
type="char"
transient="false"
@@ -21191,6 +21246,17 @@
visibility="public"
>
</field>
+<field name="SHORTCUT_MIME_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""vnd.android.cursor.item/vnd.android.search.suggest""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SUGGEST_COLUMN_FORMAT"
type="java.lang.String"
transient="false"
@@ -21279,6 +21345,28 @@
visibility="public"
>
</field>
+<field name="SUGGEST_COLUMN_SHORTCUT_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""suggest_shortcut_id""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""suggest_spinner_while_refreshing""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SUGGEST_COLUMN_TEXT_1"
type="java.lang.String"
transient="false"
@@ -21312,6 +21400,17 @@
visibility="public"
>
</field>
+<field name="SUGGEST_NEVER_MAKE_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""_-1""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SUGGEST_URI_PATH_QUERY"
type="java.lang.String"
transient="false"
@@ -21323,6 +21422,17 @@
visibility="public"
>
</field>
+<field name="SUGGEST_URI_PATH_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""search_suggest_shortcut""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USER_QUERY"
type="java.lang.String"
transient="false"
diff --git a/api/current.xml b/api/current.xml
index 7e6c2df..d8609ec 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -4695,6 +4695,17 @@
visibility="public"
>
</field>
+<field name="killAfterRestore"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843416"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="label"
type="int"
transient="false"
@@ -6477,6 +6488,17 @@
visibility="public"
>
</field>
+<field name="restoreNeedsApplication"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843417"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="right"
type="int"
transient="false"
@@ -18039,6 +18061,50 @@
visibility="public"
>
</field>
+<field name="FLAG_FOREGROUND"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_PERSISTENT_PROCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_STARTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SYSTEM_PROCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="activeSince"
type="long"
transient="false"
@@ -18069,6 +18135,16 @@
visibility="public"
>
</field>
+<field name="flags"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="foreground"
type="boolean"
transient="false"
@@ -18139,6 +18215,16 @@
visibility="public"
>
</field>
+<field name="uid"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ActivityManager.RunningTaskInfo"
extends="java.lang.Object"
@@ -64966,6 +65052,39 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="getAntibanding"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getColorEffect"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFlashMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getInt"
return="int"
abstract="false"
@@ -64979,6 +65098,39 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="getJpegQuality"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getJpegThumbnailQuality"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getJpegThumbnailSize"
+ return="android.hardware.Camera.Size"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getPictureFormat"
return="int"
abstract="false"
@@ -65034,6 +65186,138 @@
visibility="public"
>
</method>
+<method name="getSceneMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedAntibanding"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedColorEffects"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedFlashModes"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPictureFormats"
+ return="java.util.List<java.lang.Integer>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPictureSizes"
+ return="java.util.List<android.hardware.Camera.Size>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewFormats"
+ return="java.util.List<java.lang.Integer>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewFrameRates"
+ return="java.util.List<java.lang.Integer>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewSizes"
+ return="java.util.List<android.hardware.Camera.Size>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedSceneModes"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedWhiteBalance"
+ return="java.util.List<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getWhiteBalance"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="remove"
return="void"
abstract="false"
@@ -65047,6 +65331,17 @@
<parameter name="key" type="java.lang.String">
</parameter>
</method>
+<method name="removeGpsData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="set"
return="void"
abstract="false"
@@ -65077,6 +65372,138 @@
<parameter name="value" type="int">
</parameter>
</method>
+<method name="setAntibanding"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="antibanding" type="java.lang.String">
+</parameter>
+</method>
+<method name="setColorEffect"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setFlashMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setGpsAltitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="altitude" type="double">
+</parameter>
+</method>
+<method name="setGpsLatitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="latitude" type="double">
+</parameter>
+</method>
+<method name="setGpsLongitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="longitude" type="double">
+</parameter>
+</method>
+<method name="setGpsTimestamp"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timestamp" type="long">
+</parameter>
+</method>
+<method name="setJpegQuality"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="quality" type="int">
+</parameter>
+</method>
+<method name="setJpegThumbnailQuality"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="quality" type="int">
+</parameter>
+</method>
+<method name="setJpegThumbnailSize"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+</method>
<method name="setPictureFormat"
return="void"
abstract="false"
@@ -65146,6 +65573,45 @@
<parameter name="height" type="int">
</parameter>
</method>
+<method name="setRotation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="rotation" type="int">
+</parameter>
+</method>
+<method name="setSceneMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setWhiteBalance"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
<method name="unflatten"
return="void"
abstract="false"
@@ -65159,6 +65625,446 @@
<parameter name="flattened" type="java.lang.String">
</parameter>
</method>
+<field name="ANTIBANDING_50HZ"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""50hz""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_60HZ"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""60hz""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""auto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_OFF"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""off""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_AQUA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""aqua""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_BLACKBOARD"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""blackboard""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_MONO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""mono""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_NEGATIVE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""negative""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_NONE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""none""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_POSTERIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""posterize""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_SEPIA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""sepia""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_SOLARIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""solarize""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_WHITEBOARD"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""whiteboard""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""auto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_OFF"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""off""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_ON"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""on""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_RED_EYE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""red-eye""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_ACTION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""action""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""auto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_BEACH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""beach""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_CANDLELIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""candlelight""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_FIREWORKS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""fireworks""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_LANDSCAPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""landscape""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_NIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""night""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_NIGHT_PORTRAIT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""night-portrait""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_PARTY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""party""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_PORTRAIT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""portrait""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SNOW"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""snow""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SPORTS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""sports""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_STEADYPHOTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""steadyphoto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SUNSET"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""sunset""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_THEATRE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""theatre""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""auto""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_CLOUDY_DAYLIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""cloudy-daylight""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_DAYLIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""daylight""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_FLUORESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""fluorescent""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_INCANDESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""incandescent""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_SHADE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""shade""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_TWILIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""twilight""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_WARM_FLUORESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""warm-fluorescent""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<interface name="Camera.PictureCallback"
abstract="true"
@@ -97544,6 +98450,8 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.os.Parcelable">
+</implements>
<constructor name="Debug.MemoryInfo"
type="android.os.Debug.MemoryInfo"
static="false"
@@ -97552,6 +98460,55 @@
visibility="public"
>
</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="readFromParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="android.os.Parcel">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dalvikPrivateDirty"
type="int"
transient="false"
@@ -117279,6 +118236,17 @@
visibility="public"
>
</method>
+<method name="hasIccCard"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="isNetworkRoaming"
return="boolean"
abstract="false"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 18713e9..3ddc922 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
+#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -34,6 +35,8 @@
static struct tm now;
+static void dump_kernel_log(const char *path, const char *title) ;
+
/* dumps the current system state to stdout */
static void dumpstate(int full) {
if (full) {
@@ -101,8 +104,12 @@
DUMP("/data/system/packages.xml");
PRINT("------ PACKAGE UID ERRORS ------");
DUMP("/data/system/uiderrors.txt");
- PRINT("------ LAST KERNEL LOG ------");
- DUMP("/data/last_kmsg");
+
+ dump_kernel_log("/data/dontpanic/last_kmsg", "RAMCONSOLE");
+ dump_kernel_log("/data/dontpanic/apanic_console",
+ "PANIC CONSOLE");
+ dump_kernel_log("/data/dontpanic/apanic_threads",
+ "PANIC THREADS");
}
PRINT("========================================================");
PRINT("== build.prop");
@@ -295,3 +302,13 @@
return 0;
}
+static void dump_kernel_log(const char *path, const char *title)
+
+{
+ printf("------ KERNEL %s LOG ------\n", title);
+ if (access(path, R_OK) < 0)
+ printf("%s: %s\n", path, strerror(errno));
+ else
+ DUMP(path);
+}
+
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 5ed8941..8cfb758 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1397,7 +1397,7 @@
Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi);
}
- if (!imsi.equals(storedImsi) && !"initial".equals(storedImsi)) {
+ if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "wiping all passwords and authtokens");
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 07520c9d..ad06fa9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -289,6 +289,11 @@
public int pid;
/**
+ * The UID that owns this service.
+ */
+ public int uid;
+
+ /**
* The name of the process this service runs in.
*/
public String process;
@@ -299,7 +304,7 @@
public boolean foreground;
/**
- * The time when the service was first made activity, either by someone
+ * The time when the service was first made active, either by someone
* starting or binding to it.
*/
public long activeSince;
@@ -332,6 +337,35 @@
*/
public long restarting;
+ /**
+ * Bit for {@link #flags}: set if this service has been
+ * explicitly started.
+ */
+ public static final int FLAG_STARTED = 1<<0;
+
+ /**
+ * Bit for {@link #flags}: set if the service has asked to
+ * run as a foreground process.
+ */
+ public static final int FLAG_FOREGROUND = 1<<1;
+
+ /**
+ * Bit for {@link #flags): set if the service is running in a
+ * core system process.
+ */
+ public static final int FLAG_SYSTEM_PROCESS = 1<<2;
+
+ /**
+ * Bit for {@link #flags): set if the service is running in a
+ * persistent process.
+ */
+ public static final int FLAG_PERSISTENT_PROCESS = 1<<3;
+
+ /**
+ * Running flags.
+ */
+ public int flags;
+
public RunningServiceInfo() {
}
@@ -342,6 +376,7 @@
public void writeToParcel(Parcel dest, int flags) {
ComponentName.writeToParcel(service, dest);
dest.writeInt(pid);
+ dest.writeInt(uid);
dest.writeString(process);
dest.writeInt(foreground ? 1 : 0);
dest.writeLong(activeSince);
@@ -350,11 +385,13 @@
dest.writeInt(crashCount);
dest.writeLong(lastActivityTime);
dest.writeLong(restarting);
+ dest.writeInt(this.flags);
}
public void readFromParcel(Parcel source) {
service = ComponentName.readFromParcel(source);
pid = source.readInt();
+ uid = source.readInt();
process = source.readString();
foreground = source.readInt() != 0;
activeSince = source.readLong();
@@ -363,6 +400,7 @@
crashCount = source.readInt();
lastActivityTime = source.readLong();
restarting = source.readLong();
+ flags = source.readInt();
}
public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d14ec15..52d6891 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -29,6 +29,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -1107,6 +1108,25 @@
reply.writeNoException();
return true;
}
+
+ case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int pid = data.readInt();
+ Debug.MemoryInfo mi = new Debug.MemoryInfo();
+ getProcessMemoryInfo(pid, mi);
+ reply.writeNoException();
+ mi.writeToParcel(reply, 0);
+ return true;
+ }
+
+ case KILL_APPLICATION_PROCESS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String processName = data.readString();
+ int uid = data.readInt();
+ killApplicationProcess(processName, uid);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -2424,6 +2444,31 @@
data.recycle();
reply.recycle();
}
+
+ public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(pid);
+ mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
+ reply.readException();
+ outInfo.readFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ }
+
+ public void killApplicationProcess(String processName, int uid) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(processName);
+ data.writeInt(uid);
+ mRemote.transact(KILL_APPLICATION_PROCESS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e915b4..8a26aba 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1463,6 +1463,10 @@
queueOrSendMessage(H.EXIT_APPLICATION, null);
}
+ public final void scheduleSuicide() {
+ queueOrSendMessage(H.SUICIDE, null);
+ }
+
public void requestThumbnail(IBinder token) {
queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
}
@@ -1546,6 +1550,10 @@
}
}
+ public void getMemoryInfo(Debug.MemoryInfo outInfo) {
+ Debug.getMemoryInfo(outInfo);
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
@@ -1748,7 +1756,8 @@
public static final int RELAUNCH_ACTIVITY = 126;
public static final int PROFILER_CONTROL = 127;
public static final int CREATE_BACKUP_AGENT = 128;
- public static final int DESTROY_BACKUP_AGENT = 129;
+ public static final int DESTROY_BACKUP_AGENT = 129;
+ public static final int SUICIDE = 130;
String codeToString(int code) {
if (localLOGV) {
switch (code) {
@@ -1782,6 +1791,7 @@
case PROFILER_CONTROL: return "PROFILER_CONTROL";
case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
+ case SUICIDE: return "SUICIDE";
}
}
return "(unknown)";
@@ -1890,6 +1900,11 @@
case DESTROY_BACKUP_AGENT:
handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
break;
+ case SUICIDE:
+ {
+ Process.killProcess(Process.myPid());
+ }
+ break;
}
}
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index ad64465..928981d 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -26,6 +26,7 @@
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.IBinder;
@@ -257,6 +258,13 @@
return true;
}
+ case SCHEDULE_SUICIDE_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ scheduleSuicide();
+ return true;
+ }
+
case REQUEST_THUMBNAIL_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
@@ -370,6 +378,16 @@
scheduleDestroyBackupAgent(appInfo);
return true;
}
+
+ case GET_MEMORY_INFO_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ Debug.MemoryInfo mi = new Debug.MemoryInfo();
+ getMemoryInfo(mi);
+ reply.writeNoException();
+ mi.writeToParcel(reply, 0);
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -641,7 +659,15 @@
IBinder.FLAG_ONEWAY);
data.recycle();
}
-
+
+ public final void scheduleSuicide() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
+ IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
+
public final void requestThumbnail(IBinder token)
throws RemoteException {
Parcel data = Parcel.obtain();
@@ -756,5 +782,16 @@
IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
+ reply.readException();
+ outInfo.readFromParcel(reply);
+ data.recycle();
+ reply.recycle();
+ }
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c3e7224..98a8481 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -30,6 +30,7 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Debug;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.IInterface;
@@ -157,6 +158,7 @@
throws RemoteException;
public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
+ public void killApplicationProcess(String processName, int uid) throws RemoteException;
public boolean startInstrumentation(ComponentName className, String profileFile,
int flags, Bundle arguments, IInstrumentationWatcher watcher)
@@ -272,6 +274,9 @@
public void closeSystemDialogs(String reason) throws RemoteException;
+ public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+ throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -428,4 +433,6 @@
int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
+ int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
+ int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 6faaa34..8dda898 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -25,6 +25,7 @@
import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.os.Debug;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.IBinder;
@@ -82,6 +83,7 @@
IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
Configuration config, Map<String, IBinder> services) throws RemoteException;
void scheduleExit() throws RemoteException;
+ void scheduleSuicide() throws RemoteException;
void requestThumbnail(IBinder token) throws RemoteException;
void scheduleConfigurationChanged(Configuration config) throws RemoteException;
void updateTimeZone() throws RemoteException;
@@ -97,6 +99,7 @@
void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
throws RemoteException;
void setSchedulingGroup(int group) throws RemoteException;
+ void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -130,4 +133,6 @@
int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
+ int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
+ int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 0a71961..0ec3243 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -266,6 +266,33 @@
return BluetoothError.ERROR_IPC;
}
+ /**
+ * Get trust state of a remote device.
+ * @hide
+ */
+ public boolean getTrustState() {
+ try {
+ return sService.getTrustState(mAddress);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return false;
+ }
+
+ /**
+ * Set trust state for a remote device.
+ * @param value the trust state value (true or false)
+ * @hide
+ */
+ public boolean setTrust(boolean value) {
+ try {
+ return sService.setTrust(mAddress, value);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return false;
+ }
+
/** @hide */
public int getBluetoothClass() {
try {
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 9e05a87..a11ceac 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -58,4 +58,6 @@
boolean setPairingConfirmation(in String address, boolean confirm);
boolean cancelPairingUserInput(in String address);
+ boolean setTrust(in String address, in boolean value);
+ boolean getTrustState(in String address);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 59529be..2a17672 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1267,6 +1267,8 @@
* enabled or disabled. The data contains the name of the package.
* <ul>
* <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
+ * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME} containing the class name of the changed component.
+ * <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the default action of restarting the application.
* </ul>
*
* <p class="note">This is a protected intent that can only be sent
@@ -2034,6 +2036,14 @@
public static final String EXTRA_REMOTE_INTENT_TOKEN =
"android.intent.extra.remote_intent_token";
+ /**
+ * Used as an int extra field in {@link android.content.Intent#ACTION_PACKAGE_CHANGED}
+ * intent to supply the name of the component that changed.
+ * @hide
+ */
+ public static final String EXTRA_CHANGED_COMPONENT_NAME =
+ "android.intent.extra.changed_component_name";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Intent flags (see mFlags variable).
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 15144a2..4e9e49c 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -148,6 +148,9 @@
private volatile boolean mSyncPollInitialized;
private final PendingIntent mSyncAlarmIntent;
private final PendingIntent mSyncPollAlarmIntent;
+ // Synchronized on "this". Instead of using this directly one should instead call
+ // its accessor, getConnManager().
+ private ConnectivityManager mConnManagerDoNotUseDirectly;
private final SyncAdaptersCache mSyncAdapters;
@@ -280,6 +283,16 @@
private final boolean mFactoryTest;
+ private ConnectivityManager getConnectivityManager() {
+ synchronized (this) {
+ if (mConnManagerDoNotUseDirectly == null) {
+ mConnManagerDoNotUseDirectly = (ConnectivityManager)mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ }
+ return mConnManagerDoNotUseDirectly;
+ }
+ }
+
public SyncManager(Context context, boolean factoryTest) {
mFactoryTest = factoryTest;
@@ -536,6 +549,14 @@
return;
}
+ if (!getConnectivityManager().getBackgroundDataSetting()) {
+ if (isLoggable) {
+ Log.v(TAG, "not syncing because background data usage isn't allowed");
+ }
+ setStatusText("Sync is disabled.");
+ return;
+ }
+
if (mAccounts == null) setStatusText("The accounts aren't known yet.");
if (!mDataConnectionIsConnected) setStatusText("No data connection");
if (mStorageIsLow) setStatusText("Memory low");
@@ -602,6 +623,8 @@
if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority);
}
+ final boolean masterSyncAutomatically = mSyncStorageEngine.getMasterSyncAutomatically();
+
for (String authority : syncableAuthorities) {
for (Account account : accounts) {
int isSyncable = mSyncStorageEngine.getIsSyncable(account, authority);
@@ -618,22 +641,36 @@
if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) {
continue;
}
+
// make this an initialization sync if the isSyncable state is unknown
Bundle extrasCopy = extras;
+ long delayCopy = delay;
if (isSyncable < 0) {
extrasCopy = new Bundle(extras);
extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
+ delayCopy = -1; // expedite this
+ } else {
+ final boolean syncAutomatically = masterSyncAutomatically
+ && mSyncStorageEngine.getSyncAutomatically(account, authority);
+ boolean syncAllowed = manualSync || syncAutomatically;
+ if (!syncAllowed) {
+ if (isLoggable) {
+ Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority
+ + " is not allowed, dropping request");
+ continue;
+ }
+ }
}
if (isLoggable) {
Log.v(TAG, "scheduleSync:"
- + " delay " + delay
+ + " delay " + delayCopy
+ ", source " + source
+ ", account " + account
+ ", authority " + authority
+ ", extras " + extrasCopy);
}
scheduleSyncOperation(
- new SyncOperation(account, source, authority, extrasCopy, delay));
+ new SyncOperation(account, source, authority, extrasCopy, delayCopy));
}
}
}
@@ -1591,9 +1628,8 @@
// found that is runnable (not disabled, etc). If that one is ready to run then
// start it, otherwise just get out.
SyncOperation op;
- final ConnectivityManager connManager = (ConnectivityManager)
- mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- final boolean backgroundDataUsageAllowed = connManager.getBackgroundDataSetting();
+ final boolean backgroundDataUsageAllowed =
+ getConnectivityManager().getBackgroundDataSetting();
synchronized (mSyncQueue) {
while (true) {
op = mSyncQueue.head();
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0a42a6f..8839f95 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -184,7 +184,29 @@
* {@hide}
*/
public static final int FLAG_ALLOW_BACKUP = 1<<14;
-
+
+ /**
+ * Value for {@link #flags}: this is false if the application has set
+ * its android:killAfterRestore to false, true otherwise.
+ *
+ * <p>If android:allowBackup is set to false or no android:backupAgent
+ * is specified, this flag will be ignored.
+ *
+ * {@hide}
+ */
+ public static final int FLAG_KILL_AFTER_RESTORE = 1<<15;
+
+ /**
+ * Value for {@link #flags}: this is true if the application has set
+ * its android:restoreNeedsApplication to true, false otherwise.
+ *
+ * <p>If android:allowBackup is set to false or no android:backupAgent
+ * is specified, this flag will be ignored.
+ *
+ * {@hide}
+ */
+ public static final int FLAG_RESTORE_NEEDS_APPLICATION = 1<<16;
+
/**
* Flags associated with the application. Any combination of
* {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
@@ -193,7 +215,8 @@
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
* {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
* {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
- * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS}.
+ * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
+ * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}.
*/
public int flags = 0;
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4399df4..b4a6fee 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1296,12 +1296,26 @@
com.android.internal.R.styleable.AndroidManifestApplication_allowBackup, true);
if (allowBackup) {
ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+
+ // backupAgent, killAfterRestore, and restoreNeedsApplication are only relevant
+ // if backup is possible for the given application.
String backupAgent = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestApplication_backupAgent);
if (backupAgent != null) {
ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
Log.v(TAG, "android:backupAgent = " + ai.backupAgentName
+ " from " + pkgName + "+" + backupAgent);
+
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_killAfterRestore,
+ true)) {
+ ai.flags |= ApplicationInfo.FLAG_KILL_AFTER_RESTORE;
+ }
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_restoreNeedsApplication,
+ false)) {
+ ai.flags |= ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION;
+ }
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 5d7af69d..57bf3f7 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -62,53 +62,53 @@
*/
public enum ConflictAlgorithm {
/**
- * When a constraint violation occurs, an immediate ROLLBACK occurs,
- * thus ending the current transaction, and the command aborts with a
- * return code of SQLITE_CONSTRAINT. If no transaction is active
+ * When a constraint violation occurs, an immediate ROLLBACK occurs,
+ * thus ending the current transaction, and the command aborts with a
+ * return code of SQLITE_CONSTRAINT. If no transaction is active
* (other than the implied transaction that is created on every command)
* then this algorithm works the same as ABORT.
*/
ROLLBACK("ROLLBACK"),
-
+
/**
- * When a constraint violation occurs,no ROLLBACK is executed
- * so changes from prior commands within the same transaction
+ * When a constraint violation occurs,no ROLLBACK is executed
+ * so changes from prior commands within the same transaction
* are preserved. This is the default behavior.
*/
ABORT("ABORT"),
-
+
/**
- * When a constraint violation occurs, the command aborts with a return
- * code SQLITE_CONSTRAINT. But any changes to the database that
- * the command made prior to encountering the constraint violation
+ * When a constraint violation occurs, the command aborts with a return
+ * code SQLITE_CONSTRAINT. But any changes to the database that
+ * the command made prior to encountering the constraint violation
* are preserved and are not backed out.
*/
FAIL("FAIL"),
-
+
/**
- * When a constraint violation occurs, the one row that contains
- * the constraint violation is not inserted or changed.
- * But the command continues executing normally. Other rows before and
- * after the row that contained the constraint violation continue to be
+ * When a constraint violation occurs, the one row that contains
+ * the constraint violation is not inserted or changed.
+ * But the command continues executing normally. Other rows before and
+ * after the row that contained the constraint violation continue to be
* inserted or updated normally. No error is returned.
*/
IGNORE("IGNORE"),
-
+
/**
* When a UNIQUE constraint violation occurs, the pre-existing rows that
- * are causing the constraint violation are removed prior to inserting
+ * are causing the constraint violation are removed prior to inserting
* or updating the current row. Thus the insert or update always occurs.
- * The command continues executing normally. No error is returned.
+ * The command continues executing normally. No error is returned.
* If a NOT NULL constraint violation occurs, the NULL value is replaced
- * by the default value for that column. If the column has no default
- * value, then the ABORT algorithm is used. If a CHECK constraint
- * violation occurs then the IGNORE algorithm is used. When this conflict
- * resolution strategy deletes rows in order to satisfy a constraint,
+ * by the default value for that column. If the column has no default
+ * value, then the ABORT algorithm is used. If a CHECK constraint
+ * violation occurs then the IGNORE algorithm is used. When this conflict
+ * resolution strategy deletes rows in order to satisfy a constraint,
* it does not invoke delete triggers on those rows.
* This behavior might change in a future release.
*/
REPLACE("REPLACE");
-
+
private final String mValue;
ConflictAlgorithm(String value) {
mValue = value;
@@ -117,7 +117,7 @@
return mValue;
}
}
-
+
/**
* Maximum Length Of A LIKE Or GLOB Pattern
* The pattern matching algorithm used in the default LIKE and GLOB implementation
@@ -180,17 +180,19 @@
private long mLockAcquiredWallTime = 0L;
private long mLockAcquiredThreadTime = 0L;
-
+
// limit the frequency of complaints about each database to one within 20 sec
- // unless run command adb shell setprop log.tag.Database VERBOSE
+ // unless run command adb shell setprop log.tag.Database VERBOSE
private static final int LOCK_WARNING_WINDOW_IN_MS = 20000;
/** If the lock is held this long then a warning will be printed when it is released. */
private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300;
private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100;
private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000;
+ private static final int SLEEP_AFTER_YIELD_QUANTUM = 500;
+
private long mLastLockMessageTime = 0L;
-
+
/** Used by native code, do not rename */
/* package */ int mNativeHandle = 0;
@@ -205,15 +207,15 @@
/** The optional factory to use when creating new Cursors */
private CursorFactory mFactory;
-
+
private WeakHashMap<SQLiteClosable, Object> mPrograms;
-
+
private final RuntimeException mLeakedException;
// package visible, since callers will access directly to minimize overhead in the case
// that logging is not enabled.
/* package */ final boolean mLogStats;
-
+
/**
* @param closable
*/
@@ -225,7 +227,7 @@
unlock();
}
}
-
+
void removeSQLiteClosable(SQLiteClosable closable) {
lock();
try {
@@ -233,8 +235,8 @@
} finally {
unlock();
}
- }
-
+ }
+
@Override
protected void onAllReferencesReleased() {
if (isOpen()) {
@@ -245,10 +247,10 @@
/**
* Attempts to release memory that SQLite holds but does not require to
* operate properly. Typically this memory will come from the page cache.
- *
+ *
* @return the number of bytes actually released
*/
- static public native int releaseMemory();
+ static public native int releaseMemory();
/**
* Control whether or not the SQLiteDatabase is made thread-safe by using locks
@@ -284,7 +286,7 @@
* touch the native sqlite3* object since it is single threaded and uses
* a polling lock contention algorithm. The lock is recursive, and may be acquired
* multiple times by the same thread. This is a no-op if mLockingEnabled is false.
- *
+ *
* @see #unlock()
*/
/* package */ void lock() {
@@ -320,7 +322,7 @@
/**
* Releases the database lock. This is a no-op if mLockingEnabled is false.
- *
+ *
* @see #unlock()
*/
/* package */ void unlock() {
@@ -350,7 +352,7 @@
private void checkLockHoldTime() {
// Use elapsed real-time since the CPU may sleep when waiting for IO
long elapsedTime = SystemClock.elapsedRealtime();
- long lockedTime = elapsedTime - mLockAcquiredWallTime;
+ long lockedTime = elapsedTime - mLockAcquiredWallTime;
if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT &&
!Log.isLoggable(TAG, Log.VERBOSE) &&
(elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) {
@@ -567,10 +569,21 @@
}
}
if (sleepAfterYieldDelay > 0) {
- try {
- Thread.sleep(sleepAfterYieldDelay);
- } catch (InterruptedException e) {
- Thread.interrupted();
+ // Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to
+ // check if anyone is using the database. If the database is not contended,
+ // retake the lock and return.
+ long remainingDelay = sleepAfterYieldDelay;
+ while (remainingDelay > 0) {
+ try {
+ Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ?
+ remainingDelay : SLEEP_AFTER_YIELD_QUANTUM);
+ } catch (InterruptedException e) {
+ Thread.interrupted();
+ }
+ remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM;
+ if (mLock.getQueueLength() == 0) {
+ break;
+ }
}
}
beginTransaction();
@@ -720,9 +733,9 @@
if (program != null) {
program.onAllReferencesReleasedFromContainer();
}
- }
+ }
}
-
+
/**
* Native call to close the database.
*/
@@ -1157,8 +1170,8 @@
/**
* Runs the provided SQL and returns a cursor over the result set.
- * The cursor will read an initial set of rows and the return to the caller.
- * It will continue to read in batches and send data changed notifications
+ * The cursor will read an initial set of rows and the return to the caller.
+ * It will continue to read in batches and send data changed notifications
* when the later batches are ready.
* @param sql the SQL query. The SQL string must not be ; terminated
* @param selectionArgs You may include ?s in where clause in the query,
@@ -1167,19 +1180,19 @@
* @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
- *
+ *
* This work is incomplete and not fully tested or reviewed, so currently
* hidden.
* @hide
*/
- public Cursor rawQuery(String sql, String[] selectionArgs,
+ public Cursor rawQuery(String sql, String[] selectionArgs,
int initialRead, int maxRead) {
SQLiteCursor c = (SQLiteCursor)rawQueryWithFactory(
null, sql, selectionArgs, null);
c.setLoadStyle(initialRead, maxRead);
return c;
}
-
+
/**
* Convenience method for inserting a row into the database.
*
@@ -1232,7 +1245,7 @@
*/
public long replace(String table, String nullColumnHack, ContentValues initialValues) {
try {
- return insertWithOnConflict(table, nullColumnHack, initialValues,
+ return insertWithOnConflict(table, nullColumnHack, initialValues,
ConflictAlgorithm.REPLACE);
} catch (SQLException e) {
Log.e(TAG, "Error inserting " + initialValues, e);
@@ -1254,7 +1267,7 @@
*/
public long replaceOrThrow(String table, String nullColumnHack,
ContentValues initialValues) throws SQLException {
- return insertWithOnConflict(table, nullColumnHack, initialValues,
+ return insertWithOnConflict(table, nullColumnHack, initialValues,
ConflictAlgorithm.REPLACE);
}
@@ -1410,7 +1423,7 @@
public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
return updateWithOnConflict(table, values, whereClause, whereArgs, null);
}
-
+
/**
* Convenience method for updating rows in the database.
*
@@ -1423,7 +1436,7 @@
* @return the number of rows affected
* @hide
*/
- public int updateWithOnConflict(String table, ContentValues values,
+ public int updateWithOnConflict(String table, ContentValues values,
String whereClause, String[] whereArgs, ConflictAlgorithm algorithm) {
if (!isOpen()) {
throw new IllegalStateException("database not open");
@@ -1440,7 +1453,7 @@
sql.append(algorithm.value());
sql.append(" ");
}
-
+
sql.append(table);
sql.append(" SET ");
@@ -1601,7 +1614,7 @@
mFlags = flags;
mPath = path;
mLogStats = "1".equals(android.os.SystemProperties.get("db.logstats"));
-
+
mLeakedException = new IllegalStateException(path +
" SQLiteDatabase created and never closed");
mFactory = factory;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index aa3b852..38c9dbc 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -17,7 +17,9 @@
package android.hardware;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.StringTokenizer;
import java.io.IOException;
@@ -38,7 +40,7 @@
*/
public class Camera {
private static final String TAG = "Camera";
-
+
// These match the enums in frameworks/base/include/ui/Camera.h
private static final int CAMERA_MSG_ERROR = 0x001;
private static final int CAMERA_MSG_SHUTTER = 0x002;
@@ -62,12 +64,12 @@
private ZoomCallback mZoomCallback;
private ErrorCallback mErrorCallback;
private boolean mOneShot;
-
+
/**
* Returns a new Camera object.
*/
- public static Camera open() {
- return new Camera();
+ public static Camera open() {
+ return new Camera();
}
Camera() {
@@ -89,32 +91,32 @@
native_setup(new WeakReference<Camera>(this));
}
-
- protected void finalize() {
- native_release();
+
+ protected void finalize() {
+ native_release();
}
-
+
private native final void native_setup(Object camera_this);
private native final void native_release();
-
+
/**
* Disconnects and releases the Camera object resources.
- * <p>It is recommended that you call this as soon as you're done with the
+ * <p>It is recommended that you call this as soon as you're done with the
* Camera object.</p>
*/
- public final void release() {
+ public final void release() {
native_release();
}
/**
* Reconnect to the camera after passing it to MediaRecorder. To save
* setup/teardown time, a client of Camera can pass an initialized Camera
- * object to a MediaRecorder to use for video recording. Once the
+ * object to a MediaRecorder to use for video recording. Once the
* MediaRecorder is done with the Camera, this method can be used to
* re-establish a connection with the camera hardware. NOTE: The Camera
* object must first be unlocked by the process that owns it before it
- * can be connected to another proces.
+ * can be connected to another process.
*
* @throws IOException if the method fails.
*
@@ -122,7 +124,7 @@
* @hide
*/
public native final void reconnect() throws IOException;
-
+
/**
* Lock the camera to prevent other processes from accessing it. To save
* setup/teardown time, a client of Camera can pass an initialized Camera
@@ -137,9 +139,9 @@
* @hide
*/
public native final int lock();
-
+
/**
- * Unlock the camera to allow aother process to access it. To save
+ * Unlock the camera to allow another process to access it. To save
* setup/teardown time, a client of Camera can pass an initialized Camera
* object to another process. This method is used to unlock the Camera
* object before handing off the Camera object to the other process.
@@ -150,12 +152,12 @@
* @hide
*/
public native final int unlock();
-
+
/**
* Sets the SurfaceHolder to be used for a picture preview. If the surface
* changed since the last call, the screen will blank. Nothing happens
* if the same surface is re-set.
- *
+ *
* @param holder the SurfaceHolder upon which to place the picture preview
* @throws IOException if the method fails.
*/
@@ -177,23 +179,27 @@
/**
* The callback that delivers the preview frames.
*
- * @param data The contents of the preview frame in getPreviewFormat()
- * format.
+ * @param data The contents of the preview frame in {@link
+ * android.hardware.Camera.Parameters#getPreviewFormat()}
+ * format. If {@link
+ * android.hardware.Camera.Parameters#setPreviewFormat(int)}
+ * is never called, the default will be the YCbCr_420_SP
+ * (NV21) format.
* @param camera The Camera service object.
*/
void onPreviewFrame(byte[] data, Camera camera);
};
-
+
/**
* Start drawing preview frames to the surface.
*/
public native final void startPreview();
-
+
/**
* Stop drawing preview frames to the surface.
*/
public native final void stopPreview();
-
+
/**
* Return current preview state.
*
@@ -201,7 +207,7 @@
* @hide
*/
public native final boolean previewEnabled();
-
+
/**
* Can be called at any time to instruct the camera to use a callback for
* each preview frame in addition to displaying it.
@@ -260,7 +266,7 @@
mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
}
return;
-
+
case CAMERA_MSG_PREVIEW_FRAME:
if (mPreviewCallback != null) {
mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera);
@@ -321,8 +327,10 @@
public interface AutoFocusCallback
{
/**
- * Callback for the camera auto focus.
- *
+ * Callback for the camera auto focus. If the camera does not support
+ * auto-focus and autoFocus is called, onAutoFocus will be called
+ * immediately with success.
+ *
* @param success true if focus was successful, false if otherwise
* @param camera the Camera service object
*/
@@ -330,10 +338,12 @@
};
/**
- * Starts auto-focus function and registers a callback function to
- * run when camera is focused. Only valid after startPreview() has
- * been called.
- *
+ * Starts auto-focus function and registers a callback function to run when
+ * camera is focused. Only valid after startPreview() has been called. If
+ * the camera does not support auto-focus, it is a no-op and {@link
+ * AutoFocusCallback#onAutoFocus(boolean, Camera)} callback will be called
+ * immediately.
+ *
* @param cb the callback to run
*/
public final void autoFocus(AutoFocusCallback cb)
@@ -361,7 +371,7 @@
public interface PictureCallback {
/**
* Callback for when a picture is taken.
- *
+ *
* @param data a byte array of the picture data
* @param camera the Camera service object
*/
@@ -369,16 +379,16 @@
};
/**
- * Triggers an asynchronous image capture. The camera service
- * will initiate a series of callbacks to the application as the
- * image capture progresses. The shutter callback occurs after
- * the image is captured. This can be used to trigger a sound
- * to let the user know that image has been captured. The raw
- * callback occurs when the raw image data is available. The jpeg
- * callback occurs when the compressed image is available. If the
- * application does not need a particular callback, a null can be
- * passed instead of a callback method.
- *
+ * Triggers an asynchronous image capture. The camera service will initiate
+ * a series of callbacks to the application as the image capture progresses.
+ * The shutter callback occurs after the image is captured. This can be used
+ * to trigger a sound to let the user know that image has been captured. The
+ * raw callback occurs when the raw image data is available (NOTE: the data
+ * may be null if the hardware does not have enough memory to make a copy).
+ * The jpeg callback occurs when the compressed image is available. If the
+ * application does not need a particular callback, a null can be passed
+ * instead of a callback method.
+ *
* @param shutter callback after the image is captured, may be null
* @param raw callback with raw image data, may be null
* @param jpeg callback with jpeg image data, may be null
@@ -390,17 +400,17 @@
private native final void native_takePicture();
/**
- * Triggers an asynchronous image capture. The camera service
- * will initiate a series of callbacks to the application as the
- * image capture progresses. The shutter callback occurs after
- * the image is captured. This can be used to trigger a sound
- * to let the user know that image has been captured. The raw
- * callback occurs when the raw image data is available. The
- * postview callback occurs when a scaled, fully processed
- * postview image is available (NOTE: not all hardware supports
- * this). The jpeg callback occurs when the compressed image is
- * available. If the application does not need a particular
- * callback, a null can be passed instead of a callback method.
+ * Triggers an asynchronous image capture. The camera service will initiate
+ * a series of callbacks to the application as the image capture progresses.
+ * The shutter callback occurs after the image is captured. This can be used
+ * to trigger a sound to let the user know that image has been captured. The
+ * raw callback occurs when the raw image data is available (NOTE: the data
+ * may be null if the hardware does not have enough memory to make a copy).
+ * The postview callback occurs when a scaled, fully processed postview
+ * image is available (NOTE: not all hardware supports this). The jpeg
+ * callback occurs when the compressed image is available. If the
+ * application does not need a particular callback, a null can be passed
+ * instead of a callback method.
*
* @param shutter callback after the image is captured, may be null
* @param raw callback with raw image data, may be null
@@ -441,14 +451,14 @@
{
mZoomCallback = cb;
}
-
+
// These match the enum in include/ui/Camera.h
/** Unspecified camerar error. @see #ErrorCallback */
public static final int CAMERA_ERROR_UNKNOWN = 1;
/** Media server died. In this case, the application must release the
* Camera object and instantiate a new one. @see #ErrorCallback */
public static final int CAMERA_ERROR_SERVER_DIED = 100;
-
+
/**
* Handles the camera error callback.
*/
@@ -474,13 +484,13 @@
{
mErrorCallback = cb;
}
-
+
private native final void native_setParameters(String params);
private native final String native_getParameters();
/**
* Sets the Parameters for pictures from this Camera service.
- *
+ *
* @param params the Parameters to use for this Camera service
*/
public void setParameters(Parameters params) {
@@ -503,7 +513,7 @@
public class Size {
/**
* Sets the dimensions for pictures.
- *
+ *
* @param w the photo width (pixels)
* @param h the photo height (pixels)
*/
@@ -519,8 +529,111 @@
/**
* Handles the parameters for pictures created by a Camera service.
+ *
+ * <p>To make camera parameters take effect, applications have to call
+ * Camera.setParameters. For example, after setWhiteBalance is called, white
+ * balance is not changed until Camera.setParameters() is called.
+ *
+ * <p>Different devices may have different camera capabilities, such as
+ * picture size or flash modes. The application should query the camera
+ * capabilities before setting parameters. For example, the application
+ * should call getSupportedColorEffects before calling setEffect. If the
+ * camera does not support color effects, getSupportedColorEffects will
+ * return null.
*/
public class Parameters {
+ // Parameter keys to communicate with the camera driver.
+ private static final String KEY_PREVIEW_SIZE = "preview-size";
+ private static final String KEY_PREVIEW_FORMAT = "preview-format";
+ private static final String KEY_PREVIEW_FRAME_RATE = "preview-frame-rate";
+ private static final String KEY_PICTURE_SIZE = "picture-size";
+ private static final String KEY_PICTURE_FORMAT = "picture-format";
+ private static final String KEY_JPEG_THUMBNAIL_WIDTH = "jpeg-thumbnail-width";
+ private static final String KEY_JPEG_THUMBNAIL_HEIGHT = "jpeg-thumbnail-height";
+ private static final String KEY_JPEG_THUMBNAIL_QUALITY = "jpeg-thumbnail-quality";
+ private static final String KEY_JPEG_QUALITY = "jpeg-quality";
+ private static final String KEY_ROTATION = "rotation";
+ private static final String KEY_GPS_LATITUDE = "gps-latitude";
+ private static final String KEY_GPS_LONGITUDE = "gps-longitude";
+ private static final String KEY_GPS_ALTITUDE = "gps-altitude";
+ private static final String KEY_GPS_TIMESTAMP = "gps-timestamp";
+ private static final String KEY_WHITE_BALANCE = "whitebalance";
+ private static final String KEY_EFFECT = "effect";
+ private static final String KEY_ANTIBANDING = "antibanding";
+ private static final String KEY_SCENE_MODE = "scene-mode";
+ private static final String KEY_FLASH_MODE = "flash-mode";
+ // Parameter key suffix for supported values.
+ private static final String SUPPORTED_VALUES_SUFFIX = "-values";
+
+ // Values for white balance settings.
+ public static final String WHITE_BALANCE_AUTO = "auto";
+ public static final String WHITE_BALANCE_INCANDESCENT = "incandescent";
+ public static final String WHITE_BALANCE_FLUORESCENT = "fluorescent";
+ public static final String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent";
+ public static final String WHITE_BALANCE_DAYLIGHT = "daylight";
+ public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight";
+ public static final String WHITE_BALANCE_TWILIGHT = "twilight";
+ public static final String WHITE_BALANCE_SHADE = "shade";
+
+ // Values for color effect settings.
+ public static final String EFFECT_NONE = "none";
+ public static final String EFFECT_MONO = "mono";
+ public static final String EFFECT_NEGATIVE = "negative";
+ public static final String EFFECT_SOLARIZE = "solarize";
+ public static final String EFFECT_SEPIA = "sepia";
+ public static final String EFFECT_POSTERIZE = "posterize";
+ public static final String EFFECT_WHITEBOARD = "whiteboard";
+ public static final String EFFECT_BLACKBOARD = "blackboard";
+ public static final String EFFECT_AQUA = "aqua";
+
+ // Values for antibanding settings.
+ public static final String ANTIBANDING_AUTO = "auto";
+ public static final String ANTIBANDING_50HZ = "50hz";
+ public static final String ANTIBANDING_60HZ = "60hz";
+ public static final String ANTIBANDING_OFF = "off";
+
+ // Values for flash mode settings.
+ /**
+ * Flash will not be fired.
+ */
+ public static final String FLASH_MODE_OFF = "off";
+ /**
+ * Flash will be fired automatically when required. The timing is
+ * decided by camera driver.
+ */
+ public static final String FLASH_MODE_AUTO = "auto";
+ /**
+ * Flash will always be fired. The timing is decided by camera driver.
+ */
+ public static final String FLASH_MODE_ON = "on";
+ /**
+ * Flash will be fired in red-eye reduction mode.
+ */
+ public static final String FLASH_MODE_RED_EYE = "red-eye";
+
+ // Values for scene mode settings.
+ public static final String SCENE_MODE_AUTO = "auto";
+ public static final String SCENE_MODE_ACTION = "action";
+ public static final String SCENE_MODE_PORTRAIT = "portrait";
+ public static final String SCENE_MODE_LANDSCAPE = "landscape";
+ public static final String SCENE_MODE_NIGHT = "night";
+ public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait";
+ public static final String SCENE_MODE_THEATRE = "theatre";
+ public static final String SCENE_MODE_BEACH = "beach";
+ public static final String SCENE_MODE_SNOW = "snow";
+ public static final String SCENE_MODE_SUNSET = "sunset";
+ public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto";
+ public static final String SCENE_MODE_FIREWORKS = "fireworks";
+ public static final String SCENE_MODE_SPORTS = "sports";
+ public static final String SCENE_MODE_PARTY = "party";
+ public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
+
+ // Formats for setPreviewFormat and setPictureFormat.
+ private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
+ private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+ private static final String PIXEL_FORMAT_RGB565 = "rgb565";
+ private static final String PIXEL_FORMAT_JPEG = "jpeg";
+
private HashMap<String, String> mMap;
private Parameters() {
@@ -543,7 +656,7 @@
* Creates a single string with all the parameters set in
* this Parameters object.
* <p>The {@link #unflatten(String)} method does the reverse.</p>
- *
+ *
* @return a String with all values from this Parameters object, in
* semi-colon delimited key-value pairs
*/
@@ -561,16 +674,16 @@
}
/**
- * Takes a flattened string of parameters and adds each one to
+ * Takes a flattened string of parameters and adds each one to
* this Parameters object.
* <p>The {@link #flatten()} method does the reverse.</p>
- *
- * @param flattened a String of parameters (key-value paired) that
+ *
+ * @param flattened a String of parameters (key-value paired) that
* are semi-colon delimited
*/
public void unflatten(String flattened) {
mMap.clear();
-
+
StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
while (tokenizer.hasMoreElements()) {
String kv = tokenizer.nextToken();
@@ -583,14 +696,14 @@
mMap.put(k, v);
}
}
-
+
public void remove(String key) {
mMap.remove(key);
}
/**
* Sets a String parameter.
- *
+ *
* @param key the key name for the parameter
* @param value the String value of the parameter
*/
@@ -609,7 +722,7 @@
/**
* Sets an integer parameter.
- *
+ *
* @param key the key name for the parameter
* @param value the int value of the parameter
*/
@@ -619,7 +732,7 @@
/**
* Returns the value of a String parameter.
- *
+ *
* @param key the key name for the parameter
* @return the String value of the parameter
*/
@@ -629,7 +742,7 @@
/**
* Returns the value of an integer parameter.
- *
+ *
* @param key the key name for the parameter
* @return the int value of the parameter
*/
@@ -639,110 +752,133 @@
/**
* Sets the dimensions for preview pictures.
- *
+ *
* @param width the width of the pictures, in pixels
* @param height the height of the pictures, in pixels
*/
public void setPreviewSize(int width, int height) {
String v = Integer.toString(width) + "x" + Integer.toString(height);
- set("preview-size", v);
+ set(KEY_PREVIEW_SIZE, v);
}
/**
* Returns the dimensions setting for preview pictures.
- *
- * @return a Size object with the height and width setting
+ *
+ * @return a Size object with the height and width setting
* for the preview picture
*/
public Size getPreviewSize() {
- String pair = get("preview-size");
- if (pair == null)
- return null;
- String[] dims = pair.split("x");
- if (dims.length != 2)
- return null;
-
- return new Size(Integer.parseInt(dims[0]),
- Integer.parseInt(dims[1]));
-
+ String pair = get(KEY_PREVIEW_SIZE);
+ return strToSize(pair);
}
/**
- * Sets the dimensions for EXIF thumbnails.
- *
+ * Gets the supported preview sizes.
+ *
+ * @return a List of Size object. null if preview size setting is not
+ * supported.
+ */
+ public List<Size> getSupportedPreviewSizes() {
+ String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitSize(str);
+ }
+
+ /**
+ * Sets the dimensions for EXIF thumbnail in Jpeg picture.
+ *
* @param width the width of the thumbnail, in pixels
* @param height the height of the thumbnail, in pixels
- *
- * FIXME: unhide before release
- * @hide
*/
- public void setThumbnailSize(int width, int height) {
- set("jpeg-thumbnail-width", width);
- set("jpeg-thumbnail-height", height);
+ public void setJpegThumbnailSize(int width, int height) {
+ set(KEY_JPEG_THUMBNAIL_WIDTH, width);
+ set(KEY_JPEG_THUMBNAIL_HEIGHT, height);
}
/**
- * Returns the dimensions for EXIF thumbnail
- *
- * @return a Size object with the height and width setting
- * for the EXIF thumbnails
+ * Returns the dimensions for EXIF thumbnail in Jpeg picture.
*
- * FIXME: unhide before release
- * @hide
+ * @return a Size object with the height and width setting for the EXIF
+ * thumbnails
*/
- public Size getThumbnailSize() {
- return new Size(getInt("jpeg-thumbnail-width"),
- getInt("jpeg-thumbnail-height"));
+ public Size getJpegThumbnailSize() {
+ return new Size(getInt(KEY_JPEG_THUMBNAIL_WIDTH),
+ getInt(KEY_JPEG_THUMBNAIL_HEIGHT));
}
/**
- * Sets the quality of the EXIF thumbnail
- *
- * @param quality the JPEG quality of the EXIT thumbnail
+ * Sets the quality of the EXIF thumbnail in Jpeg picture.
*
- * FIXME: unhide before release
- * @hide
+ * @param quality the JPEG quality of the EXIF thumbnail. The range is 1
+ * to 100, with 100 being the best.
*/
- public void setThumbnailQuality(int quality) {
- set("jpeg-thumbnail-quality", quality);
+ public void setJpegThumbnailQuality(int quality) {
+ set(KEY_JPEG_THUMBNAIL_QUALITY, quality);
}
/**
- * Returns the quality setting for the EXIF thumbnail
- *
- * @return the JPEG quality setting of the EXIF thumbnail
+ * Returns the quality setting for the EXIF thumbnail in Jpeg picture.
*
- * FIXME: unhide before release
- * @hide
+ * @return the JPEG quality setting of the EXIF thumbnail.
*/
- public int getThumbnailQuality() {
- return getInt("jpeg-thumbnail-quality");
+ public int getJpegThumbnailQuality() {
+ return getInt(KEY_JPEG_THUMBNAIL_QUALITY);
+ }
+
+ /**
+ * Sets Jpeg quality of captured picture.
+ *
+ * @param quality the JPEG quality of captured picture. The range is 1
+ * to 100, with 100 being the best.
+ */
+ public void setJpegQuality(int quality) {
+ set(KEY_JPEG_QUALITY, quality);
+ }
+
+ /**
+ * Returns the quality setting for the JPEG picture.
+ *
+ * @return the JPEG picture quality setting.
+ */
+ public int getJpegQuality() {
+ return getInt(KEY_JPEG_QUALITY);
}
/**
* Sets the rate at which preview frames are received.
- *
+ *
* @param fps the frame rate (frames per second)
*/
public void setPreviewFrameRate(int fps) {
- set("preview-frame-rate", fps);
+ set(KEY_PREVIEW_FRAME_RATE, fps);
}
/**
* Returns the setting for the rate at which preview frames
* are received.
- *
+ *
* @return the frame rate setting (frames per second)
*/
public int getPreviewFrameRate() {
- return getInt("preview-frame-rate");
+ return getInt(KEY_PREVIEW_FRAME_RATE);
}
/**
- * Sets the image format for preview pictures.
- *
- * @param pixel_format the desired preview picture format
- * (<var>PixelFormat.YCbCr_420_SP</var>,
+ * Gets the supported preview frame rates.
+ *
+ * @return a List of Integer objects (preview frame rates). null if
+ * preview frame rate setting is not supported.
+ */
+ public List<Integer> getSupportedPreviewFrameRates() {
+ String str = get(KEY_PREVIEW_FRAME_RATE + SUPPORTED_VALUES_SUFFIX);
+ return splitInt(str);
+ }
+
+ /**
+ * Sets the image format for preview pictures. If this is never called,
+ * the default will be the YCbCr_420_SP (NV21) format.
+ *
+ * @param pixel_format the desired preview picture format
+ * (<var>PixelFormat.YCbCr_420_SP (NV21)</var>,
* <var>PixelFormat.RGB_565</var>, or
* <var>PixelFormat.JPEG</var>)
* @see android.graphics.PixelFormat
@@ -750,56 +886,73 @@
public void setPreviewFormat(int pixel_format) {
String s = cameraFormatForPixelFormat(pixel_format);
if (s == null) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException(
+ "Invalid pixel_format=" + pixel_format);
}
- set("preview-format", s);
+ set(KEY_PREVIEW_FORMAT, s);
}
/**
- * Returns the image format for preview pictures.
- *
+ * Returns the image format for preview pictures got from
+ * {@link PreviewCallback}.
+ *
* @return the PixelFormat int representing the preview picture format
+ * @see android.graphics.PixelFormat
*/
public int getPreviewFormat() {
- return pixelFormatForCameraFormat(get("preview-format"));
+ return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT));
+ }
+
+ /**
+ * Gets the supported preview formats.
+ *
+ * @return a List of Integer objects. null if preview format setting is
+ * not supported.
+ */
+ public List<Integer> getSupportedPreviewFormats() {
+ String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
+ return splitInt(str);
}
/**
* Sets the dimensions for pictures.
- *
+ *
* @param width the width for pictures, in pixels
* @param height the height for pictures, in pixels
*/
public void setPictureSize(int width, int height) {
String v = Integer.toString(width) + "x" + Integer.toString(height);
- set("picture-size", v);
+ set(KEY_PICTURE_SIZE, v);
}
/**
* Returns the dimension setting for pictures.
- *
- * @return a Size object with the height and width setting
+ *
+ * @return a Size object with the height and width setting
* for pictures
*/
public Size getPictureSize() {
- String pair = get("picture-size");
- if (pair == null)
- return null;
- String[] dims = pair.split("x");
- if (dims.length != 2)
- return null;
+ String pair = get(KEY_PICTURE_SIZE);
+ return strToSize(pair);
+ }
- return new Size(Integer.parseInt(dims[0]),
- Integer.parseInt(dims[1]));
-
+ /**
+ * Gets the supported picture sizes.
+ *
+ * @return a List of Size objects. null if picture size setting is not
+ * supported.
+ */
+ public List<Size> getSupportedPictureSizes() {
+ String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitSize(str);
}
/**
* Sets the image format for pictures.
- *
- * @param pixel_format the desired picture format
- * (<var>PixelFormat.YCbCr_420_SP</var>,
+ *
+ * @param pixel_format the desired picture format
+ * (<var>PixelFormat.YCbCr_420_SP (NV21)</var>,
* <var>PixelFormat.RGB_565</var>, or
* <var>PixelFormat.JPEG</var>)
* @see android.graphics.PixelFormat
@@ -807,27 +960,39 @@
public void setPictureFormat(int pixel_format) {
String s = cameraFormatForPixelFormat(pixel_format);
if (s == null) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException(
+ "Invalid pixel_format=" + pixel_format);
}
- set("picture-format", s);
+ set(KEY_PICTURE_FORMAT, s);
}
/**
* Returns the image format for pictures.
- *
+ *
* @return the PixelFormat int representing the picture format
*/
public int getPictureFormat() {
- return pixelFormatForCameraFormat(get("picture-format"));
+ return pixelFormatForCameraFormat(get(KEY_PICTURE_FORMAT));
+ }
+
+ /**
+ * Gets the supported picture formats.
+ *
+ * @return a List of Integer objects (values are PixelFormat.XXX). null
+ * if picture setting is not supported.
+ */
+ public List<Integer> getSupportedPictureFormats() {
+ String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitInt(str);
}
private String cameraFormatForPixelFormat(int pixel_format) {
switch(pixel_format) {
- case PixelFormat.YCbCr_422_SP: return "yuv422sp";
- case PixelFormat.YCbCr_420_SP: return "yuv420sp";
- case PixelFormat.RGB_565: return "rgb565";
- case PixelFormat.JPEG: return "jpeg";
+ case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP;
+ case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP;
+ case PixelFormat.RGB_565: return PIXEL_FORMAT_RGB565;
+ case PixelFormat.JPEG: return PIXEL_FORMAT_JPEG;
default: return null;
}
}
@@ -836,21 +1001,309 @@
if (format == null)
return PixelFormat.UNKNOWN;
- if (format.equals("yuv422sp"))
+ if (format.equals(PIXEL_FORMAT_YUV422SP))
return PixelFormat.YCbCr_422_SP;
- if (format.equals("yuv420sp"))
+ if (format.equals(PIXEL_FORMAT_YUV420SP))
return PixelFormat.YCbCr_420_SP;
- if (format.equals("rgb565"))
+ if (format.equals(PIXEL_FORMAT_RGB565))
return PixelFormat.RGB_565;
- if (format.equals("jpeg"))
+ if (format.equals(PIXEL_FORMAT_JPEG))
return PixelFormat.JPEG;
return PixelFormat.UNKNOWN;
}
+ /**
+ * Sets the orientation of the device in degrees, which instructs the
+ * camera driver to rotate the picture and thumbnail, in order to match
+ * what the user sees from the viewfinder. For example, suppose the
+ * natural position of the device is landscape. If the user takes a
+ * picture in landscape mode in 2048x1536 resolution, the rotation
+ * should be set to 0. If the user rotates the phone 90 degrees
+ * clockwise, the rotation should be set to 90. Applications can use
+ * {@link android.view.OrientationEventListener} to set this parameter.
+ *
+ * Since the picture is rotated, the orientation in the EXIF header is
+ * missing or always 1 (row #0 is top and column #0 is left side).
+ *
+ * @param rotation The orientation of the device in degrees. Rotation
+ * can only be 0, 90, 180 or 270.
+ * @throws IllegalArgumentException if rotation value is invalid.
+ * @see android.view.OrientationEventListener
+ */
+ public void setRotation(int rotation) {
+ if (rotation == 0 || rotation == 90 || rotation == 180
+ || rotation == 270) {
+ set(KEY_ROTATION, Integer.toString(rotation));
+ } else {
+ throw new IllegalArgumentException(
+ "Invalid rotation=" + rotation);
+ }
+ }
+
+ /**
+ * Sets GPS latitude coordinate. This will be stored in JPEG EXIF
+ * header.
+ *
+ * @param latitude GPS latitude coordinate.
+ */
+ public void setGpsLatitude(double latitude) {
+ set(KEY_GPS_LATITUDE, Double.toString(latitude));
+ }
+
+ /**
+ * Sets GPS longitude coordinate. This will be stored in JPEG EXIF
+ * header.
+ *
+ * @param longitude GPS longitude coordinate.
+ */
+ public void setGpsLongitude(double longitude) {
+ set(KEY_GPS_LONGITUDE, Double.toString(longitude));
+ }
+
+ /**
+ * Sets GPS altitude. This will be stored in JPEG EXIF header.
+ *
+ * @param altitude GPS altitude in meters.
+ */
+ public void setGpsAltitude(double altitude) {
+ set(KEY_GPS_ALTITUDE, Double.toString(altitude));
+ }
+
+ /**
+ * Sets GPS timestamp. This will be stored in JPEG EXIF header.
+ *
+ * @param timestamp GPS timestamp (UTC in seconds since January 1,
+ * 1970).
+ */
+ public void setGpsTimestamp(long timestamp) {
+ set(KEY_GPS_TIMESTAMP, Long.toString(timestamp));
+ }
+
+ /**
+ * Removes GPS latitude, longitude, altitude, and timestamp from the
+ * parameters.
+ */
+ public void removeGpsData() {
+ remove(KEY_GPS_LATITUDE);
+ remove(KEY_GPS_LONGITUDE);
+ remove(KEY_GPS_ALTITUDE);
+ remove(KEY_GPS_TIMESTAMP);
+ }
+
+ /**
+ * Gets the current white balance setting.
+ *
+ * @return one of WHITE_BALANCE_XXX string constant. null if white
+ * balance setting is not supported.
+ */
+ public String getWhiteBalance() {
+ return get(KEY_WHITE_BALANCE);
+ }
+
+ /**
+ * Sets the white balance.
+ *
+ * @param value WHITE_BALANCE_XXX string constant.
+ */
+ public void setWhiteBalance(String value) {
+ set(KEY_WHITE_BALANCE, value);
+ }
+
+ /**
+ * Gets the supported white balance.
+ *
+ * @return a List of WHITE_BALANCE_XXX string constants. null if white
+ * balance setting is not supported.
+ */
+ public List<String> getSupportedWhiteBalance() {
+ String str = get(KEY_WHITE_BALANCE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
+ * Gets the current color effect setting.
+ *
+ * @return one of EFFECT_XXX string constant. null if color effect
+ * setting is not supported.
+ */
+ public String getColorEffect() {
+ return get(KEY_EFFECT);
+ }
+
+ /**
+ * Sets the current color effect setting.
+ *
+ * @param value EFFECT_XXX string constants.
+ */
+ public void setColorEffect(String value) {
+ set(KEY_EFFECT, value);
+ }
+
+ /**
+ * Gets the supported color effects.
+ *
+ * @return a List of EFFECT_XXX string constants. null if color effect
+ * setting is not supported.
+ */
+ public List<String> getSupportedColorEffects() {
+ String str = get(KEY_EFFECT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+
+ /**
+ * Gets the current antibanding setting.
+ *
+ * @return one of ANTIBANDING_XXX string constant. null if antibanding
+ * setting is not supported.
+ */
+ public String getAntibanding() {
+ return get(KEY_ANTIBANDING);
+ }
+
+ /**
+ * Sets the antibanding.
+ *
+ * @param antibanding ANTIBANDING_XXX string constant.
+ */
+ public void setAntibanding(String antibanding) {
+ set(KEY_ANTIBANDING, antibanding);
+ }
+
+ /**
+ * Gets the supported antibanding values.
+ *
+ * @return a List of ANTIBANDING_XXX string constants. null if
+ * antibanding setting is not supported.
+ */
+ public List<String> getSupportedAntibanding() {
+ String str = get(KEY_ANTIBANDING + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
+ * Gets the current scene mode setting.
+ *
+ * @return one of SCENE_MODE_XXX string constant. null if scene mode
+ * setting is not supported.
+ */
+ public String getSceneMode() {
+ return get(KEY_SCENE_MODE);
+ }
+
+ /**
+ * Sets the scene mode.
+ *
+ * @param value SCENE_MODE_XXX string constants.
+ */
+ public void setSceneMode(String value) {
+ set(KEY_SCENE_MODE, value);
+ }
+
+ /**
+ * Gets the supported scene modes.
+ *
+ * @return a List of SCENE_MODE_XXX string constant. null if scene mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedSceneModes() {
+ String str = get(KEY_SCENE_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
+ * Gets the current flash mode setting.
+ *
+ * @return one of FLASH_MODE_XXX string constant. null if flash mode
+ * setting is not supported.
+ */
+ public String getFlashMode() {
+ return get(KEY_FLASH_MODE);
+ }
+
+ /**
+ * Sets the flash mode.
+ *
+ * @param value FLASH_MODE_XXX string constants.
+ */
+ public void setFlashMode(String value) {
+ set(KEY_FLASH_MODE, value);
+ }
+
+ /**
+ * Gets the supported flash modes.
+ *
+ * @return a List of FLASH_MODE_XXX string constants. null if flash mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedFlashModes() {
+ String str = get(KEY_FLASH_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ // Splits a comma delimited string to an ArrayList of String.
+ // Return null if the passing string is null or the size is 0.
+ private ArrayList<String> split(String str) {
+ if (str == null) return null;
+
+ // Use StringTokenizer because it is faster than split.
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ ArrayList<String> substrings = new ArrayList<String>();
+ while (tokenizer.hasMoreElements()) {
+ substrings.add(tokenizer.nextToken());
+ }
+ return substrings;
+ }
+
+ // Splits a comma delimited string to an ArrayList of Integer.
+ // Return null if the passing string is null or the size is 0.
+ private ArrayList<Integer> splitInt(String str) {
+ if (str == null) return null;
+
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ ArrayList<Integer> substrings = new ArrayList<Integer>();
+ while (tokenizer.hasMoreElements()) {
+ String token = tokenizer.nextToken();
+ substrings.add(Integer.parseInt(token));
+ }
+ if (substrings.size() == 0) return null;
+ return substrings;
+ }
+
+ // Splits a comma delimited string to an ArrayList of Size.
+ // Return null if the passing string is null or the size is 0.
+ private ArrayList<Size> splitSize(String str) {
+ if (str == null) return null;
+
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ ArrayList<Size> sizeList = new ArrayList<Size>();
+ while (tokenizer.hasMoreElements()) {
+ Size size = strToSize(tokenizer.nextToken());
+ if (size != null) sizeList.add(size);
+ }
+ if (sizeList.size() == 0) return null;
+ return sizeList;
+ }
+
+ // Parses a string (ex: "480x320") to Size object.
+ // Return null if the passing string is null.
+ private Size strToSize(String str) {
+ if (str == null) return null;
+
+ int pos = str.indexOf('x');
+ if (pos != -1) {
+ String width = str.substring(0, pos);
+ String height = str.substring(pos + 1);
+ return new Size(Integer.parseInt(width),
+ Integer.parseInt(height));
+ }
+ Log.e(TAG, "Invalid size parameter string=" + str);
+ return null;
+ }
};
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index b0fc78e..5352cf6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -104,7 +104,7 @@
* This class is used to retrieved various statistics about the memory mappings for this
* process. The returns info broken down by dalvik, native, and other. All results are in kB.
*/
- public static class MemoryInfo {
+ public static class MemoryInfo implements Parcelable {
/** The proportional set size for dalvik. */
public int dalvikPss;
/** The private dirty pages used by dalvik. */
@@ -125,6 +125,50 @@
public int otherPrivateDirty;
/** The shared dirty pages used by everything else. */
public int otherSharedDirty;
+
+ public MemoryInfo() {
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(dalvikPss);
+ dest.writeInt(dalvikPrivateDirty);
+ dest.writeInt(dalvikSharedDirty);
+ dest.writeInt(nativePss);
+ dest.writeInt(nativePrivateDirty);
+ dest.writeInt(nativeSharedDirty);
+ dest.writeInt(otherPss);
+ dest.writeInt(otherPrivateDirty);
+ dest.writeInt(otherSharedDirty);
+ }
+
+ public void readFromParcel(Parcel source) {
+ dalvikPss = source.readInt();
+ dalvikPrivateDirty = source.readInt();
+ dalvikSharedDirty = source.readInt();
+ nativePss = source.readInt();
+ nativePrivateDirty = source.readInt();
+ nativeSharedDirty = source.readInt();
+ otherPss = source.readInt();
+ otherPrivateDirty = source.readInt();
+ otherSharedDirty = source.readInt();
+ }
+
+ public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
+ public MemoryInfo createFromParcel(Parcel source) {
+ return new MemoryInfo(source);
+ }
+ public MemoryInfo[] newArray(int size) {
+ return new MemoryInfo[size];
+ }
+ };
+
+ private MemoryInfo(Parcel source) {
+ readFromParcel(source);
+ }
}
@@ -556,6 +600,13 @@
public static native void getMemoryInfo(MemoryInfo memoryInfo);
/**
+ * Note: currently only works when the requested pid has the same UID
+ * as the caller.
+ * @hide
+ */
+ public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
+
+ /**
* Establish an object allocation limit in the current thread. Useful
* for catching regressions in code that is expected to operate
* without causing any allocations.
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 6b491ab..84753ee 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -59,6 +59,8 @@
/** Valid tag values. Extend as necessary for your needs. */
public enum Tag {
+ APANIC_CONSOLE,
+ APANIC_THREADS,
AUTOTEST_FAILURE,
AUTOTEST_SEQUENCE_BEGIN,
AUTOTEST_SUITE_BEGIN,
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e48f539..2b67946 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -289,6 +289,32 @@
}
/**
+ * Computes a content URI (see {@link #CONTENT_URI}) given a lookup URI.
+ * <p>
+ * Returns null if the contact cannot be found.
+ */
+ public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) {
+ if (lookupUri == null) {
+ return null;
+ }
+
+ Cursor c = resolver.query(lookupUri, new String[]{Contacts._ID}, null, null, null);
+ if (c == null) {
+ return null;
+ }
+
+ try {
+ if (c.moveToFirst()) {
+ long contactId = c.getLong(0);
+ return ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+ }
+ } finally {
+ c.close();
+ }
+ return null;
+ }
+
+ /**
* The content:// style URI for this table joined with useful data from
* {@link Data}.
*
@@ -991,13 +1017,13 @@
private Phone() {}
/** MIME type used when storing this in data table. */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone";
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of
* phones.
*/
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone";
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
/**
* The content:// style URI for all data records of the
@@ -1076,7 +1102,7 @@
private Email() {}
/** MIME type used when storing this in data table. */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email";
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2";
/**
* The content:// style URI for all data records of the
@@ -1114,13 +1140,14 @@
}
/** MIME type used when storing this in data table. */
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/postal-address";
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/postal-address_v2";
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of
* postal addresses.
*/
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address";
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address_v2";
/**
* The content:// style URI for all data records of the
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 4425e51..073ae6c 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -1548,11 +1548,12 @@
getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_UNREAD_CONVERSATIONS);
// There seems to be a race condition here that can get the label maps into a bad
// state and lose state on a particular label.
- if (unreadConversations == null) {
- return 0;
- } else {
- return unreadConversations;
+ int result = 0;
+ if (unreadConversations != null) {
+ result = unreadConversations < 0 ? 0 : unreadConversations;
}
+
+ return result;
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 77d1740..125ed0b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2231,6 +2231,32 @@
public static final String BACKGROUND_DATA = "background_data";
/**
+ * The time in msec, when the LAST_KMSG file was send to the checkin server.
+ * We will only send the LAST_KMSG file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_LAST_KMSG_TIME = "checkin_kmsg_time";
+
+ /**
+ * The time in msec, when the apanic_console file was send to the checkin server.
+ * We will only send the apanic_console file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_APANIC_CONSOLE_TIME =
+ "checkin_apanic_console_time";
+
+ /**
+ * The time in msec, when the apanic_thread file was send to the checkin server.
+ * We will only send the apanic_thread file if it was modified after this time.
+ *
+ * @hide
+ */
+ public static final String CHECKIN_SEND_APANIC_THREAD_TIME =
+ "checkin_apanic_thread_time";
+
+ /**
* The CDMA roaming mode 0 = Home Networks, CDMA default
* 1 = Roaming on Affiliated networks
* 2 = Roaming on any networks
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 0207330..4584382 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -558,6 +558,23 @@
"android.provider.Telephony.SIM_FULL";
/**
+ * Broadcast Action: An incoming SMS has been rejected by the
+ * telephony framework. This intent is sent in lieu of any
+ * of the RECEIVED_ACTION intents. The intent will have the
+ * following extra value:</p>
+ *
+ * <ul>
+ * <li><em>result</em> - An int result code, eg,
+ * <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
+ * indicating the error returned to the network.</li>
+ * </ul>
+
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String SMS_REJECTED_ACTION =
+ "android.provider.Telephony.SMS_REJECTED";
+
+ /**
* Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
* {@link #DATA_SMS_RECEIVED_ACTION} intent.
*
@@ -1522,6 +1539,9 @@
public static final Uri CONTENT_DRAFT_URI = Uri.parse(
"content://mms-sms/draft");
+ public static final Uri CONTENT_LOCKED_URI = Uri.parse(
+ "content://mms-sms/locked");
+
/***
* Pass in a query parameter called "pattern" which is the text
* to search for.
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 79a7cf8..8cef3a2 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -347,7 +347,12 @@
} else {
mBluetoothService.getBondState().setBondState(address,
BluetoothDevice.BOND_NOT_BONDED);
+ mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false");
}
+ } else if (name.equals("Trusted")) {
+ if (DBG)
+ log("set trust state succeded, value is " + propValues[1]);
+ mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
}
}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 21104c8..b168850 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -885,6 +885,42 @@
}
/**
+ * Sets the remote device trust state.
+ *
+ * @return boolean to indicate operation success or fail
+ */
+ public synchronized boolean setTrust(String address, boolean value) {
+ if (!BluetoothDevice.checkBluetoothAddress(address)) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return false;
+ }
+
+ return setDevicePropertyBooleanNative(getObjectPathFromAddress(address), "Trusted",
+ value ? 1 : 0);
+ }
+
+ /**
+ * Gets the remote device trust state as boolean.
+ * Note: this value may be
+ * retrieved from cache if we retrieved the data before *
+ *
+ * @return boolean to indicate trust or untrust state
+ */
+ public synchronized boolean getTrustState(String address) {
+ if (!BluetoothDevice.checkBluetoothAddress(address)) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return false;
+ }
+
+ String val = getRemoteDeviceProperty(address, "Trusted");
+ if (val == null) {
+ return false;
+ } else {
+ return val.equals("true") ? true : false;
+ }
+ }
+
+ /**
* Gets the remote major, minor classes encoded as a 32-bit
* integer.
*
@@ -1220,5 +1256,6 @@
private native boolean setPasskeyNative(String address, int passkey, int nativeData);
private native boolean setPairingConfirmationNative(String address, boolean confirm,
int nativeData);
+ private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
}
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 29dc2ea52..a92800d 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1527,7 +1527,7 @@
if (bm != null) {
workPaint.set(paint);
Styled.measureText(paint, workPaint, text,
- offset, offset + 1, null);
+ j, j + 2, null);
float wid = (float) bm.getWidth() *
-workPaint.ascent() / bm.getHeight();
diff --git a/core/java/android/webkit/ContentLoader.java b/core/java/android/webkit/ContentLoader.java
index 27cd6b5..19aa087 100644
--- a/core/java/android/webkit/ContentLoader.java
+++ b/core/java/android/webkit/ContentLoader.java
@@ -57,6 +57,16 @@
}
+ private String errString(Exception ex) {
+ String exMessage = ex.getMessage();
+ String errString = mContext.getString(
+ com.android.internal.R.string.httpErrorFileNotFound);
+ if (exMessage != null) {
+ errString += " " + exMessage;
+ }
+ return errString;
+ }
+
@Override
protected boolean setupStreamAndSendStatus() {
Uri uri = Uri.parse(mUrl);
@@ -73,28 +83,16 @@
mDataStream = mContext.getContentResolver().openInputStream(uri);
mHandler.status(1, 1, 0, "OK");
} catch (java.io.FileNotFoundException ex) {
- mHandler.error(
- EventHandler.FILE_NOT_FOUND_ERROR,
- mContext.getString(
- com.android.internal.R.string.httpErrorFileNotFound) +
- " " + ex.getMessage());
+ mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
return false;
} catch (java.io.IOException ex) {
- mHandler.error(
- EventHandler.FILE_ERROR,
- mContext.getString(
- com.android.internal.R.string.httpErrorFileNotFound) +
- " " + ex.getMessage());
+ mHandler.error(EventHandler.FILE_ERROR, errString(ex));
return false;
} catch (RuntimeException ex) {
// readExceptionWithFileNotFoundExceptionFromParcel in DatabaseUtils
// can throw a serial of RuntimeException. Catch them all here.
- mHandler.error(
- EventHandler.FILE_ERROR,
- mContext.getString(
- com.android.internal.R.string.httpErrorFileNotFound) +
- " " + ex.getMessage());
+ mHandler.error(EventHandler.FILE_ERROR, errString(ex));
return false;
}
return true;
diff --git a/core/java/android/webkit/FileLoader.java b/core/java/android/webkit/FileLoader.java
index 54a4c1d..085f1f4 100644
--- a/core/java/android/webkit/FileLoader.java
+++ b/core/java/android/webkit/FileLoader.java
@@ -72,6 +72,15 @@
}
}
+ private String errString(Exception ex) {
+ String exMessage = ex.getMessage();
+ String errString = mContext.getString(R.string.httpErrorFileNotFound);
+ if (exMessage != null) {
+ errString += " " + exMessage;
+ }
+ return errString;
+ }
+
@Override
protected boolean setupStreamAndSendStatus() {
try {
@@ -95,16 +104,11 @@
mHandler.status(1, 1, 0, "OK");
} catch (java.io.FileNotFoundException ex) {
- mHandler.error(
- EventHandler.FILE_NOT_FOUND_ERROR,
- mContext.getString(R.string.httpErrorFileNotFound) +
- " " + ex.getMessage());
+ mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
return false;
} catch (java.io.IOException ex) {
- mHandler.error(EventHandler.FILE_ERROR,
- mContext.getString(R.string.httpErrorFileNotFound) +
- " " + ex.getMessage());
+ mHandler.error(EventHandler.FILE_ERROR, errString(ex));
return false;
}
return true;
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 43c76a8..1a5b2eb 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -606,6 +606,7 @@
// before calling it.
if (mCacheLoader != null) {
mCacheLoader.load();
+ mFromCache = true;
if (DebugFlags.LOAD_LISTENER) {
Log.v(LOGTAG, "LoadListener cache load url=" + url());
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index f474f15..081250b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1244,6 +1244,18 @@
}
}
+ private synchronized boolean hasMessages(int what) {
+ if (mBlockMessages) {
+ return false;
+ }
+ if (mMessages != null) {
+ Log.w(LOGTAG, "hasMessages() is not supported in this case.");
+ return false;
+ } else {
+ return mHandler.hasMessages(what);
+ }
+ }
+
private synchronized void sendMessageDelayed(Message msg, long delay) {
if (mBlockMessages) {
return;
@@ -1355,9 +1367,22 @@
// We don't want anyone to post a message between removing pending
// messages and sending the destroy message.
synchronized (mEventHub) {
+ // RESUME_TIMERS and PAUSE_TIMERS are per process base. They need to
+ // be preserved even the WebView is destroyed.
+ // Note: we should not have more than one RESUME_TIMERS/PAUSE_TIMERS
+ boolean hasResume = mEventHub.hasMessages(EventHub.RESUME_TIMERS);
+ boolean hasPause = mEventHub.hasMessages(EventHub.PAUSE_TIMERS);
mEventHub.removeMessages();
mEventHub.sendMessageAtFrontOfQueue(
Message.obtain(null, EventHub.DESTROY));
+ if (hasPause) {
+ mEventHub.sendMessageAtFrontOfQueue(
+ Message.obtain(null, EventHub.PAUSE_TIMERS));
+ }
+ if (hasResume) {
+ mEventHub.sendMessageAtFrontOfQueue(
+ Message.obtain(null, EventHub.RESUME_TIMERS));
+ }
mEventHub.blockMessages();
mWebView = null;
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index b179a13..2f28d9f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -651,6 +651,7 @@
if (mProgress > max) {
mProgress = max;
+ refreshProgress(R.id.progress, mProgress, false);
}
}
}
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 8bae3e4..ce0c9cb 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -425,6 +425,11 @@
}
public void onClick(View view) {
+ // Make sure there is a contact
+ if (mContactUri == null) {
+ return;
+ }
+
switch (view.getId()) {
case R.id.star: {
// Toggle "starred" state
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index b4c60f1..3ee404a 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -200,12 +200,13 @@
fclose(fp);
}
-static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
+static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
+ jint pid, jobject object)
{
stats_t stats;
memset(&stats, 0, sizeof(stats_t));
- load_maps(getpid(), &stats);
+ load_maps(pid, &stats);
env->SetIntField(object, dalvikPss_field, stats.dalvikPss);
env->SetIntField(object, dalvikPrivateDirty_field, stats.dalvikPrivateDirty);
@@ -220,6 +221,11 @@
env->SetIntField(object, otherSharedDirty_field, stats.otherSharedDirty);
}
+static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
+{
+ android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
+}
+
static jint read_binder_stat(const char* stat)
{
FILE* fp = fopen(BINDER_STATS, "r");
@@ -281,6 +287,8 @@
(void*) android_os_Debug_getNativeHeapFreeSize },
{ "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V",
(void*) android_os_Debug_getDirtyPages },
+ { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V",
+ (void*) android_os_Debug_getDirtyPagesPid },
{ "getBinderSentTransactions", "()I",
(void*) android_os_Debug_getBinderSentTransactions },
{ "getBinderReceivedTransactions", "()I",
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 1bfabd7..8fe7487 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -227,37 +227,58 @@
const char * get_adapter_path(DBusConnection *conn) {
- DBusMessage *msg, *reply;
+ DBusMessage *msg, *reply = NULL;
DBusError err;
const char *device_path = NULL;
- msg = dbus_message_new_method_call("org.bluez", "/",
- "org.bluez.Manager", "DefaultAdapter");
- if (!msg) {
- LOGE("%s: Can't allocate new method call for GetProperties!",
- __FUNCTION__);
- return NULL;
- }
- dbus_message_append_args(msg, DBUS_TYPE_INVALID);
+ int attempt = 0;
- dbus_error_init(&err);
- reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
- dbus_message_unref(msg);
-
- if (!reply) {
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
+ for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
+ msg = dbus_message_new_method_call("org.bluez", "/",
+ "org.bluez.Manager", "DefaultAdapter");
+ if (!msg) {
+ LOGE("%s: Can't allocate new method call for get_adapter_path!",
+ __FUNCTION__);
+ return NULL;
}
- return NULL;
+ dbus_message_append_args(msg, DBUS_TYPE_INVALID);
+ dbus_error_init(&err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ if (dbus_error_has_name(&err,
+ "org.freedesktop.DBus.Error.ServiceUnknown")) {
+ // bluetoothd is still down, retry
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ usleep(10000); // 10 ms
+ continue;
+ } else {
+ // Some other error we weren't expecting
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ }
+ }
+ goto failed;
+ }
}
+ if (attempt == 1000) {
+ LOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
+ goto failed;
+ }
+
if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
&device_path, DBUS_TYPE_INVALID)
|| !device_path){
if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
}
- return NULL;
+ goto failed;
}
+ dbus_message_unref(msg);
return device_path;
+
+failed:
+ dbus_message_unref(msg);
+ return NULL;
}
static int register_agent(native_data_t *nat,
@@ -274,6 +295,9 @@
}
nat->adapter = get_adapter_path(nat->conn);
+ if (nat->adapter == NULL) {
+ return -1;
+ }
msg = dbus_message_new_method_call("org.bluez", nat->adapter,
"org.bluez.Adapter", "RegisterAgent");
if (!msg) {
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index d1901b4..de921f1 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -646,6 +646,7 @@
if (!msg) {
LOGE("%s: Can't allocate new method call for GetProperties!",
__FUNCTION__);
+ env->ReleaseStringUTFChars(key, c_key);
return JNI_FALSE;
}
@@ -701,6 +702,60 @@
#endif
}
+static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
+ jstring key, void *value, jint type) {
+#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
+ native_data_t *nat = get_native_data(env, object);
+ if (nat) {
+ DBusMessage *reply, *msg;
+ DBusMessageIter iter;
+ DBusError err;
+
+ const char *c_key = env->GetStringUTFChars(key, NULL);
+ const char *c_path = env->GetStringUTFChars(path, NULL);
+
+ dbus_error_init(&err);
+ msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
+ c_path, DBUS_DEVICE_IFACE, "SetProperty");
+ if (!msg) {
+ LOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
+ env->ReleaseStringUTFChars(key, c_key);
+ env->ReleaseStringUTFChars(path, c_path);
+ return JNI_FALSE;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
+ dbus_message_iter_init_append(msg, &iter);
+ append_variant(&iter, type, value);
+
+ reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ env->ReleaseStringUTFChars(key, c_key);
+ env->ReleaseStringUTFChars(path, c_path);
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+ }
+#endif
+ return JNI_FALSE;
+}
+
+static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
+ jstring path, jstring key, jint value) {
+#ifdef HAVE_BLUETOOTH
+ return setDevicePropertyNative(env, object, path, key,
+ (void *)&value, DBUS_TYPE_BOOLEAN);
+#else
+ return JNI_FALSE;
+#endif
+}
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
@@ -740,6 +795,8 @@
{"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
{"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
(void *)cancelPairingUserInputNative},
+ {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
+ (void *)setDevicePropertyBooleanNative},
};
int register_android_server_BluetoothService(JNIEnv *env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1ea5fa3..53e0125 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1113,6 +1113,7 @@
android:label="@string/android_system_label"
android:allowClearUserData="false"
android:backupAgent="com.android.server.SystemBackupAgent"
+ android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_android">
<activity android:name="com.android.internal.app.ChooserActivity"
android:theme="@style/Theme.Dialog.Alert"
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
new file mode 100644
index 0000000..58d2dbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
new file mode 100644
index 0000000..cd1afe9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
new file mode 100644
index 0000000..c398d6f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
new file mode 100644
index 0000000..e1eb5b0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_connected_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_connected_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_in_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_in_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_inandout_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_inandout_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_out_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_out_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
index 42c8ab4..82ba310 100644
--- a/core/res/res/values-en-rUS/donottranslate-names.xml
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -147,7 +147,7 @@
MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
</string>
<string name="common_last_name_prefixes">
- D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
+ D\', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
</string>
<string name="common_name_conjunctions">
&, AND, OR
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index ce421db..7aaf218 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -580,6 +580,15 @@
<!-- This is not the attribute you are looking for. -->
<attr name="allowBackup" format="boolean" />
+ <!-- Whether the application in question should be terminated after its
+ settings have been restored. The default is to do so. -->
+ <attr name="killAfterRestore" format="boolean" />
+
+ <!-- Whether the application needs to have its own Application subclass
+ active during restore. The default is to run restore with a minimal
+ Application class to avoid interference with application logic. -->
+ <attr name="restoreNeedsApplication" format="boolean" />
+
<!-- The <code>manifest</code> tag is the root of an
<code>AndroidManifest.xml</code> file,
describing the contents of an Android package (.apk) file. One
@@ -656,6 +665,8 @@
<attr name="testOnly" />
<attr name="backupAgent" />
<attr name="allowBackup" />
+ <attr name="killAfterRestore" />
+ <attr name="restoreNeedsApplication" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0fba0f6..1a362f7 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1155,10 +1155,11 @@
<public type="attr" name="wallpaperActivityOpenExitAnimation" />
<public type="attr" name="wallpaperActivityCloseEnterAnimation" />
<public type="attr" name="wallpaperActivityCloseExitAnimation" />
+ <public type="attr" name="supportsUploading" />
+ <public type="attr" name="killAfterRestore" />
+ <public type="attr" name="restoreNeedsApplication" />
<public type="style" name="Theme.Wallpaper" />
<public type="style" name="Theme.Wallpaper.NoTitleBar" />
<public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
-
- <public type="attr" name="supportsUploading" />
</resources>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 0248985..e508392 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -15,20 +15,60 @@
<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
<dt>description:</dt>
-<dd>This element specifies a specific feature used by the application.
+<dd>This element declares a specific feature used by the application.
Android provides some features that may not be equally supported by all
Android devices. In a manner similar to the <code><a href="uses-sdk-element.html"><uses-sdk></a></code>
-element, this element allows an application to specify which potentially variable
-features it requires. In this way, the application
-will not be installed on devices that do not offer the required feature.</p>
+element, this element allows an application to specify which device-variable
+features it uses. In this way, the application
+will not be installed on devices that do not offer the feature.</p>
-<p>For example, an application might specify that it requires a certain version of Open GL.
-If a device does not support that version of Open GL, then it will not allow installation of the application.</p>
+<p>For example, an application might specify that it requires a camera with auto-focus capabilities.
+If a device does not provide a camera with auto-focus, then it will not allow
+installation of the application.</p>
+
+<p>In order to maintain strict device compatibility, it's very important that you use
+this element to declare all features that your application uses. Failure to declare
+a feature may result your application being installed on a device
+that does not support the feature and your application failing.</p>
+
+<p>For some features, there may exist a specfic attribute that allows you to define
+a version of the feature, such as the version of Open GL used (declared with
+<a href="#glEsVersion">{@code glEsVersion}</a>). Other features that either do or do not
+exist for a device, such as camera auto-focus, are declared using the
+<a href="#name">{@code name}</a> attribute.</p>
+
+<p>Any software or hardware features that may vary among Android-powered
+devices will be listed on this page among the attributes below. If you see any features
+here that you use in your application, you should include a {@code
+<uses-feature>} element for each one. For example, if your application uses the device
+camera, then you should include the following in your {@code AndroidManifest.xml}:</p>
+
+<pre>
+<uses-feature android:name="android.hardware.camera" />
+</pre>
+
+<p>If you declare "android.hardware.camera", then your application is considered
+compatible with all devices that include a camera, regardless of whether auto-focus is
+available or not. If you also use the auto-focus features (available through the {@link
+android.hardware.Camera Camera API}), then you need to include an additional
+{@code <uses-feature>} element that declares the "android.hardware.camera.autofocus"
+feature. Also note that you must still request the {@link android.Manifest.permission#CAMERA
+CAMERA permission}. Requesting permission grants your application access to the
+appropriate hardware and software, while declaring the features used by
+your application ensures proper device compatibility.</p>
+
+<p>Although the {@code <uses-feature>} element is only activated for devices running
+API Level 4 or higher, it is safe to include this for applications that declare
+a <a href="uses-sdk-element.html#min">{@code minSdkVersion}</a>
+of "3" or lower. Devices running older versions of the platform
+will simply ignore this element, but newer devices will recognize it and enforce
+installation restrictions based on whether the device supports the feature.</p>
<p class="note"><strong>Note:</strong>
For each feature required by your application, you must include a new {@code
<uses-feature>} element. Multiple features cannot be declared in one
instance of this element.</p>
+
</dd>
@@ -51,16 +91,30 @@
<table>
<tr>
+ <th>Feature</th>
<th>Value</th>
<th>Description</th>
</tr><tr>
+ <td rowspan="3">Camera</td>
<td>"{@code android.hardware.camera}"</td>
<td>The application requires a camera.</td>
</tr><tr>
<td>"{@code android.hardware.camera.autofocus}"</td>
<td>The application requires a camera with auto-focus capability.
As a prerequisite, "{@code android.hardware.camera}" must also be declared
- with a separate {@code <uses-feature>} element.</td>
+ with a separate {@code <uses-feature>} element.
+ </td>
+ <tr>
+ <td colspan="2">
+ <strong>Note:</strong> Any application that requests the
+ {@link android.Manifest.permission#CAMERA CAMERA permission} but does <em>not</em>
+ declare any camera features with the {@code <uses-feature>} element will be assumed
+ to use all camera features (such as auto-focus). Thus, the application will not
+ be compatible with devices that do not support all features. Please use
+ {@code <uses-feature>} to declare only the camera features that your
+ application needs.
+ </td>
+ </tr>
</tr>
</table>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index adcdc28..ee8d03d 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -3,7 +3,10 @@
<dl class="xml">
<dt>syntax:</dt>
-<dd><pre class="stx"><uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" /></pre></dd>
+<dd><pre>
+<uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>"
+ android:<a href="#max">maxSdkVersion</a>="<i>integer</i>"
+ android:<a href="#target">targetSdkVersion</a>="<i>integer</i>" /></pre></dd>
<dt>contained in:</dt>
<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
@@ -64,12 +67,16 @@
<dt><a name="target"></a>{@code android:targetSdkVersion}</dt>
<dd>An integer designating the API Level that the application is targetting.
- <p>With this attribute set, the application says that is is be able to run on
+ <p>With this attribute set, the application says that it is able to run on
older versions (down to {@code minSdkVersion}), but was explicitly tested to work
with the version specified here.
- Specifying this version allows the platform to disable compatibility
- code that is not required or enable newer features that are not
- available to older applications.</p>
+ Specifying this target version allows the platform to disable compatibility
+ settings that are not required for the target version (which may otherwise be turned on
+ in order to maintain forward-compatibility) or enable newer features that are not
+ available to older applications. This does not mean that you can program different
+ features for different versions of the platform—it simply informs the platform that you
+ have tested against the target version and the platform should not perform any extra
+ work to maintain forward-compatibility with the target version.</p>
<p>Introduced in: API Level 4</p>
</dd>
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 29cdf21..5b0e0b4 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -136,7 +136,7 @@
void clearCodecSpecificData();
void setAMRFormat();
- void setAACFormat();
+ void setAACFormat(int32_t numChannels, int32_t sampleRate);
status_t setVideoPortFormatType(
OMX_U32 portIndex,
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index d1174ad..6caeb3e 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -163,15 +163,9 @@
return ret;
}
}
- while ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
- if (i++ > 0) {
- if ((ret = sKeystore.put(CA_CERTIFICATE, keyname + i, pemData)) != 0) {
- return ret;
- }
- } else {
- if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
- return ret;
- }
+ if ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
+ if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
+ return ret;
}
}
return 0;
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
index 006a0a3..91114d6 100644
--- a/keystore/jni/cert.c
+++ b/keystore/jni/cert.c
@@ -212,13 +212,14 @@
}
err:
if (bio) BIO_free(bio);
- return (len == 0) ? -1 : 0;
+ return len;
}
int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
{
if ((p12store != NULL) && (p12store->cert != NULL)) {
- return convert_to_pem((void*)p12store->cert, 1, buf, size);
+ int len = convert_to_pem((void*)p12store->cert, 1, buf, size);
+ return (len == 0) ? -1 : 0;
}
return -1;
}
@@ -226,7 +227,8 @@
int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
{
if ((p12store != NULL) && (p12store->pkey != NULL)) {
- return convert_to_pem((void*)p12store->pkey, 0, buf, size);
+ int len = convert_to_pem((void*)p12store->pkey, 0, buf, size);
+ return (len == 0) ? -1 : 0;
}
return -1;
}
@@ -234,12 +236,19 @@
int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
{
X509 *cert = NULL;
+ int len = 0;
- if ((p12store != NULL) && (p12store->certs != NULL) &&
- ((cert = sk_X509_pop(p12store->certs)) != NULL)) {
- int ret = convert_to_pem((void*)cert, 1, buf, size);
- X509_free(cert);
- return ret;
+ if ((p12store != NULL) && (p12store->certs != NULL)) {
+ while (((cert = sk_X509_pop(p12store->certs)) != NULL) && (len < size)) {
+ int s = convert_to_pem((void*)cert, 1, buf + len, size - len);
+ if (s == 0) {
+ LOGE("buffer size is too small. len=%d size=%d\n", len, size);
+ return -1;
+ }
+ len += s;
+ X509_free(cert);
+ }
+ return (len == 0) ? -1 : 0;
}
return -1;
}
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 3a419b5..ef71641 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1449,6 +1449,8 @@
int j = activeTracks.indexOf(t);
if (j >= 0) {
mActiveTracks.add(t);
+ // force buffer refilling and no ramp volume when the track is mixed for the first time
+ t->mFillingUpStatus = Track::FS_FILLING;
}
}
}
@@ -3512,10 +3514,11 @@
if (tracks.size()) {
dstThread->putTracks(tracks, activeTracks);
}
- dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
}
}
+ dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
+
return NO_ERROR;
}
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
index 8c1cad4..99f4048 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.c
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -4,45 +4,44 @@
#pragma stateFragment(default)
#pragma stateFragmentStore(default)
+struct PartStruct {float dx; float dy; float x; float y; int c;};
+int newPart = 0;
+
int main(int launchID) {
int ct;
int count = Control_count - 1;
int rate = Control_rate;
- float *dataF = loadArrayF(1, 0);
float height = getHeight();
+ struct PartStruct * p = (struct PartStruct *)loadArrayF(1, 0);
if (rate) {
- int *dataI = loadArrayI32(1, 0);
float rMax = ((float)rate) * 0.005f;
int x = Control_x;
int y = Control_y;
- int newPart = loadI32(1, count * 5);
int c = colorFloatRGBAtoUNorm8(Control_r, Control_g, Control_b, 0.99f);
while (rate--) {
- int idx = newPart * 5;
- vec2Rand(dataF + idx, rMax);
- dataF[idx + 2] = x;
- dataF[idx + 3] = y;
- dataI[idx + 4] = c;
+ vec2Rand((float *)(p + newPart), rMax);
+ p[newPart].x = x;
+ p[newPart].y = y;
+ p[newPart].c = c;
newPart++;
if (newPart >= count) {
newPart = 0;
}
}
- storeI32(1, count * 5, newPart);
}
for (ct=0; ct < count; ct++) {
- float dy = dataF[1] + 0.15f;
- float posy = dataF[3] + dy;
+ float dy = p->dy + 0.15f;
+ float posy = p->y + dy;
if ((posy > height) && (dy > 0)) {
dy *= -0.3f;
}
- dataF[1] = dy;
- dataF[2] += dataF[0];
- dataF[3] = posy;
- dataF += 5;
+ p->dy = dy;
+ p->x += p->dx;
+ p->y = posy;
+ p++;
}
uploadToBufferObject(NAMED_PartBuffer);
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 0831f4a..f80843d 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3284,7 +3284,16 @@
break;
}
if (c == '\'' && (quoted == 0 || quoted == '\'')) {
- break;
+ /*
+ * In practice, when people write ' instead of \'
+ * in a string, they are doing it by accident
+ * instead of really meaning to use ' as a quoting
+ * character. Warn them so they don't lose it.
+ */
+ if (outErrorMsg) {
+ *outErrorMsg = "Apostrophe not preceded by \\";
+ }
+ return false;
}
}
p++;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 098ddbd..6af7df9 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -174,7 +174,7 @@
*http_status = -1;
mHeaders.clear();
- char line[256];
+ char line[1024];
status_t err = receive_line(line, sizeof(line));
if (err != OK) {
return err;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3a065ae..7c8defc 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -302,7 +302,11 @@
codec->setAMRFormat();
}
if (!createEncoder && !strcasecmp("audio/mp4a-latm", mime)) {
- codec->setAACFormat();
+ int32_t numChannels, sampleRate;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+ CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+
+ codec->setAACFormat(numChannels, sampleRate);
}
if (!strncasecmp(mime, "video/", 6)) {
int32_t width, height;
@@ -1321,10 +1325,6 @@
return;
}
- // We're going to temporarily give up the lock while reading data
- // from the source. A certain client unfortunately chose to have the
- // thread supplying input data and reading output data be the same...
-
MediaBuffer *srcBuffer;
status_t err;
if (mSeekTimeUs >= 0) {
@@ -1332,13 +1332,10 @@
options.setSeekTo(mSeekTimeUs);
mSeekTimeUs = -1;
- mLock.unlock();
err = mSource->read(&srcBuffer, &options);
} else {
- mLock.unlock();
err = mSource->read(&srcBuffer);
}
- mLock.lock();
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
OMX_TICKS timestamp = 0;
@@ -1496,20 +1493,22 @@
}
}
-void OMXCodec::setAACFormat() {
- OMX_AUDIO_PARAM_AACPROFILETYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
- def.nPortIndex = kPortIndexInput;
+void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
+ OMX_AUDIO_PARAM_AACPROFILETYPE profile;
+ profile.nSize = sizeof(profile);
+ profile.nVersion.s.nVersionMajor = 1;
+ profile.nVersion.s.nVersionMinor = 1;
+ profile.nPortIndex = kPortIndexInput;
status_t err =
- mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+ mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
- def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+ profile.nChannels = numChannels;
+ profile.nSampleRate = sampleRate;
+ profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
- err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+ err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
CHECK_EQ(err, OK);
}
@@ -2123,8 +2122,19 @@
inputFormat->findInt32(kKeyChannelCount, &numChannels);
inputFormat->findInt32(kKeySampleRate, &sampleRate);
+ if ((OMX_U32)numChannels != params.nChannels) {
+ LOGW("Codec outputs a different number of channels than "
+ "the input stream contains.");
+ }
+
mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
- mOutputFormat->setInt32(kKeyChannelCount, numChannels);
+
+ // Use the codec-advertised number of channels, as some
+ // codecs appear to output stereo even if the input data is
+ // mono.
+ mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
+
+ // The codec-reported sampleRate is not reliable...
mOutputFormat->setInt32(kKeySampleRate, sampleRate);
break;
}
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index af0a1bd..1e1d729 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -8,6 +8,7 @@
android:label="@string/app_label"
android:process="system"
android:backupAgent="SettingsBackupAgent"
+ android:killAfterRestore="false"
android:icon="@drawable/ic_launcher_settings">
<provider android:name="SettingsProvider" android:authorities="settings"
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 071a90d..0ec8dab 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -41,7 +41,7 @@
#define FILTER_LOWSHELF_ATTENUATION -18.0f // in dB
#define FILTER_TRANSITION_FREQ 1100.0f // in Hz
#define FILTER_SHELF_SLOPE 1.0f // Q
-#define FILTER_GAIN 6.0f // linear gain
+#define FILTER_GAIN 5.5f // linear gain
// such a huge gain is justified by how much energy in the low frequencies is "wasted" at the output
// of the synthesis. The low shelving filter removes it, leaving room for amplification.
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 4eed7fe..0e60dd6 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -557,7 +557,12 @@
Log.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
for (PackageInfo p : targetPkgs) {
Log.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName
- + " uid=" + p.applicationInfo.uid);
+ + " uid=" + p.applicationInfo.uid
+ + " killAfterRestore="
+ + (((p.applicationInfo.flags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) ? "true" : "false")
+ + " restoreNeedsApplication="
+ + (((p.applicationInfo.flags & ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION) != 0) ? "true" : "false")
+ );
}
}
@@ -1244,11 +1249,21 @@
+ "] is compatible with installed version ["
+ packageInfo.versionCode + "]");
- // Now perform the actual restore
+ // Now perform the actual restore: first clear the app's data
+ // if appropriate
clearApplicationDataSynchronous(packageName);
+
+ // Then set up and bind the agent (with a restricted Application object
+ // unless the application says otherwise)
+ boolean useRealApp = (packageInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION) != 0;
+ if (DEBUG && useRealApp) {
+ Log.v(TAG, "agent requires real Application subclass for restore");
+ }
IBackupAgent agent = bindToAgentSynchronous(
packageInfo.applicationInfo,
- IApplicationThread.BACKUP_MODE_RESTORE);
+ (useRealApp ? IApplicationThread.BACKUP_MODE_INCREMENTAL
+ : IApplicationThread.BACKUP_MODE_RESTORE));
if (agent == null) {
Log.w(TAG, "Can't find backup agent for " + packageName);
EventLog.writeEvent(RESTORE_AGENT_FAILURE_EVENT, packageName,
@@ -1256,12 +1271,26 @@
continue;
}
+ // And then finally run the restore on this agent
try {
processOneRestore(packageInfo, metaInfo.versionCode, agent);
++count;
} finally {
- // unbind even on timeout or failure, just in case
+ // unbind and tidy up even on timeout or failure, just in case
mActivityManager.unbindBackupAgent(packageInfo.applicationInfo);
+
+ // The agent was probably running with a stub Application object,
+ // which isn't a valid run mode for the main app logic. Shut
+ // down the app so that next time it's launched, it gets the
+ // usual full initialization.
+ if ((packageInfo.applicationInfo.flags
+ & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) {
+ if (DEBUG) Log.d(TAG, "Restore complete, killing host process of "
+ + packageInfo.applicationInfo.processName);
+ mActivityManager.killApplicationProcess(
+ packageInfo.applicationInfo.processName,
+ packageInfo.applicationInfo.uid);
+ }
}
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 8ec6ec3..14cd7a8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -62,6 +62,8 @@
import android.os.Build;
import android.os.Bundle;
import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
import android.os.Parcel;
import android.os.RemoteException;
import android.os.Environment;
@@ -140,7 +142,7 @@
final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
Process.THREAD_PRIORITY_BACKGROUND);
- final Handler mHandler;
+ final PackageHandler mHandler;
final int mSdkVersion = Build.VERSION.SDK_INT;
final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
@@ -272,6 +274,49 @@
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ // Set of pending broadcasts for aggregating enable/disable of components.
+ final HashMap<String, String> mPendingBroadcasts = new HashMap<String, String>();
+ static final int SEND_PENDING_BROADCAST = 1;
+ // Delay time in millisecs
+ static final int BROADCAST_DELAY = 10 * 1000;
+
+ class PackageHandler extends Handler {
+ PackageHandler(Looper looper) {
+ super(looper);
+ }
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SEND_PENDING_BROADCAST : {
+ int size = 0;
+ String broadcastList[];
+ HashMap<String, String> tmpMap;
+ int uids[];
+ synchronized (mPackages) {
+ size = mPendingBroadcasts.size();
+ if (size <= 0) {
+ // Nothing to be done. Just return
+ return;
+ }
+ broadcastList = new String[size];
+ mPendingBroadcasts.keySet().toArray(broadcastList);
+ tmpMap = new HashMap<String, String>(mPendingBroadcasts);
+ uids = new int[size];
+ for (int i = 0; i < size; i++) {
+ PackageSetting ps = mSettings.mPackages.get(mPendingBroadcasts.get(broadcastList[i]));
+ uids[i] = (ps != null) ? ps.userId : -1;
+ }
+ mPendingBroadcasts.clear();
+ }
+ // Send broadcasts
+ for (int i = 0; i < size; i++) {
+ String className = broadcastList[i];
+ sendPackageChangedBroadcast(className, true, tmpMap.get(className), uids[i]);
+ }
+ break;
+ }
+ }
+ }
+ }
public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
ServiceManager.addService("package", m);
@@ -355,7 +400,7 @@
synchronized (mInstallLock) {
synchronized (mPackages) {
mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper());
+ mHandler = new PackageHandler(mHandlerThread.getLooper());
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
@@ -4866,7 +4911,7 @@
}
private void setEnabledSetting(
- final String packageNameStr, String classNameStr, int newState, final int flags) {
+ final String packageName, String className, int newState, final int flags) {
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED)) {
@@ -4878,17 +4923,20 @@
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+ boolean sendNow = false;
+ boolean isApp = (className == null);
+ String key = isApp ? packageName : className;
int packageUid = -1;
synchronized (mPackages) {
- pkgSetting = mSettings.mPackages.get(packageNameStr);
+ pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
- if (classNameStr == null) {
+ if (className == null) {
throw new IllegalArgumentException(
- "Unknown package: " + packageNameStr);
+ "Unknown package: " + packageName);
}
throw new IllegalArgumentException(
- "Unknown component: " + packageNameStr
- + "/" + classNameStr);
+ "Unknown component: " + packageName
+ + "/" + className);
}
if (!allowedByPermission && (uid != pkgSetting.userId)) {
throw new SecurityException(
@@ -4896,41 +4944,67 @@
+ Binder.getCallingPid()
+ ", uid=" + uid + ", package uid=" + pkgSetting.userId);
}
- packageUid = pkgSetting.userId;
- if (classNameStr == null) {
+ if (className == null) {
// We're dealing with an application/package level state change
pkgSetting.enabled = newState;
} else {
// We're dealing with a component level state change
switch (newState) {
case COMPONENT_ENABLED_STATE_ENABLED:
- pkgSetting.enableComponentLP(classNameStr);
+ pkgSetting.enableComponentLP(className);
break;
case COMPONENT_ENABLED_STATE_DISABLED:
- pkgSetting.disableComponentLP(classNameStr);
+ pkgSetting.disableComponentLP(className);
break;
case COMPONENT_ENABLED_STATE_DEFAULT:
- pkgSetting.restoreComponentLP(classNameStr);
+ pkgSetting.restoreComponentLP(className);
break;
default:
Log.e(TAG, "Invalid new component state: " + newState);
+ return;
}
}
mSettings.writeLP();
+ packageUid = pkgSetting.userId;
+ if ((flags&PackageManager.DONT_KILL_APP) == 0) {
+ sendNow = true;
+ // Purge entry from pending broadcast list if another one exists already
+ // since we are sending one right away.
+ if (mPendingBroadcasts.get(key) != null) {
+ mPendingBroadcasts.remove(key);
+ // Can ignore empty list since its handled in the handler anyway
+ }
+ } else {
+ if (mPendingBroadcasts.get(key) == null) {
+ mPendingBroadcasts.put(key, packageName);
+ }
+ if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
+ // Schedule a message
+ mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+ }
+ }
}
-
+
long callingId = Binder.clearCallingIdentity();
try {
- Bundle extras = new Bundle(2);
- extras.putBoolean(Intent.EXTRA_DONT_KILL_APP,
- (flags&PackageManager.DONT_KILL_APP) != 0);
- extras.putInt(Intent.EXTRA_UID, packageUid);
- sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageNameStr, extras);
+ if (sendNow) {
+ sendPackageChangedBroadcast(packageName,
+ (flags&PackageManager.DONT_KILL_APP) != 0, key, packageUid);
+ }
} finally {
Binder.restoreCallingIdentity(callingId);
}
}
+ private void sendPackageChangedBroadcast(String packageName,
+ boolean killFlag, String componentName, int packageUid) {
+ Bundle extras = new Bundle(2);
+ extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentName);
+ extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
+ extras.putInt(Intent.EXTRA_UID, packageUid);
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras);
+ }
+
public String getInstallerPackageName(String packageName) {
synchronized (mPackages) {
PackageSetting pkg = mSettings.mPackages.get(packageName);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d4e69c0..252a6d2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -68,6 +68,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
@@ -4895,6 +4896,52 @@
Binder.restoreCallingIdentity(origId);
}
+ public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi)
+ throws RemoteException {
+ ProcessRecord proc;
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(pid);
+ }
+
+ if (proc == null) {
+ throw new RemoteException();
+ }
+
+ IApplicationThread thread = proc.thread;
+ if (thread == null) {
+ throw new RemoteException();
+ }
+
+ thread.getMemoryInfo(mi);
+ }
+
+ public void killApplicationProcess(String processName, int uid) {
+ if (processName == null) {
+ return;
+ }
+
+ int callerUid = Binder.getCallingUid();
+ // Only the system server can kill an application
+ if (callerUid == Process.SYSTEM_UID) {
+ synchronized (this) {
+ ProcessRecord app = getProcessRecordLocked(processName, uid);
+ if (app != null) {
+ try {
+ app.thread.scheduleSuicide();
+ } catch (RemoteException e) {
+ // If the other end already died, then our work here is done.
+ }
+ } else {
+ Log.w(TAG, "Process/uid not found attempting kill of "
+ + processName + " / " + uid);
+ }
+ }
+ } else {
+ throw new SecurityException(callerUid + " cannot kill app process: " +
+ processName);
+ }
+ }
+
private void restartPackageLocked(final String packageName, int uid) {
uninstallPackageLocked(packageName, uid, false);
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
@@ -9818,6 +9865,7 @@
if (r.app != null) {
info.pid = r.app.pid;
}
+ info.uid = r.appInfo.uid;
info.process = r.processName;
info.foreground = r.isForeground;
info.activeSince = r.createTime;
@@ -9825,6 +9873,18 @@
info.clientCount = r.connections.size();
info.crashCount = r.crashCount;
info.lastActivityTime = r.lastActivity;
+ if (r.isForeground) {
+ info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
+ }
+ if (r.startRequested) {
+ info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
+ }
+ if (r.app != null && r.app.pid == Process.myPid()) {
+ info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
+ }
+ if (r.app != null && r.app.persistent) {
+ info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
+ }
return info;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f3304a3..a690e3c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -481,6 +481,13 @@
public static final int SIM_STATE_READY = 5;
/**
+ * @return true if a ICC card is present
+ */
+ public boolean hasIccCard() {
+ return PhoneFactory.getDefaultPhone().getIccCard().hasIccCard();
+ }
+
+ /**
* Returns a constant indicating the state of the
* device SIM card.
*
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 6657060..200340e 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -667,6 +667,19 @@
return false;
}
+ /**
+ * @return true if a ICC card is present
+ */
+ public boolean hasIccCard() {
+ boolean isIccPresent;
+ if (mPhone.getPhoneName().equals("GSM")) {
+ return mIccCardStatus.getCardState().isCardPresent();
+ } else {
+ // TODO: Make work with a CDMA device with a RUIM card.
+ return false;
+ }
+ }
+
private void log(String msg) {
Log.d(mLogTag, "[IccCard] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 7efaa2e..d26a092 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -150,7 +150,8 @@
private static SmsMessage mSmsMessage;
private static SmsMessageBase mSmsMessageBase;
private SmsMessageBase.SubmitPduBase mSubmitPduBase;
- private boolean mStorageAvailable = true;
+
+ protected boolean mStorageAvailable = true;
protected static int getNextConcatenatedRef() {
sConcatenatedRef += 1;
@@ -294,19 +295,15 @@
sms = (SmsMessage) ar.result;
try {
- if (mStorageAvailable) {
- int result = dispatchMessage(sms.mWrappedSmsMessage);
- if (result != Activity.RESULT_OK) {
- // RESULT_OK means that message was broadcast for app(s) to handle.
- // Any other result, we should ack here.
- boolean handled = (result == Intents.RESULT_SMS_HANDLED);
- acknowledgeLastIncomingSms(handled, result, null);
- }
- } else {
- acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null);
+ int result = dispatchMessage(sms.mWrappedSmsMessage);
+ if (result != Activity.RESULT_OK) {
+ // RESULT_OK means that message was broadcast for app(s) to handle.
+ // Any other result, we should ack here.
+ boolean handled = (result == Intents.RESULT_SMS_HANDLED);
+ notifyAndAcknowledgeLastIncomingSms(handled, result, null);
}
} catch (RuntimeException ex) {
- acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
+ notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
}
break;
@@ -866,6 +863,25 @@
int result, Message response);
/**
+ * Notify interested apps if the framework has rejected an incoming SMS,
+ * and send an acknowledge message to the network.
+ * @param success indicates that last message was successfully received.
+ * @param result result code indicating any error
+ * @param response callback message sent when operation completes.
+ */
+ private void notifyAndAcknowledgeLastIncomingSms(boolean success,
+ int result, Message response) {
+ if (!success) {
+ // broadcast SMS_REJECTED_ACTION intent
+ Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
+ intent.putExtra("result", result);
+ mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+ mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
+ }
+ acknowledgeLastIncomingSms(success, result, response);
+ }
+
+ /**
* Check if a SmsTracker holds multi-part Sms
*
* @param tracker a SmsTracker could hold a multi-part Sms
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index e73039b..3f0213b 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -383,7 +383,7 @@
* 2. [x@y][ ]/[body]
*/
String[] parts = messageBody.split("( /)|( )", 2);
- if (parts.length < 1 || parts[0].indexOf('@') == -1) return;
+ if (parts.length < 1) return;
emailFrom = parts[0];
emailBody = parts[1];
isEmail = true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index ca15a03..1e3a2e1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -33,6 +33,7 @@
import android.util.Config;
import android.util.Log;
import android.telephony.SmsManager;
+import android.telephony.SmsMessage.MessageClass;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.CommandsInterface;
@@ -91,23 +92,8 @@
int teleService = sms.getTeleService();
boolean handled = false;
- if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService) &&
- (SmsEnvelope.TELESERVICE_VMN != teleService)) {
- if (Config.LOGD) {
- Log.d(TAG, "Received SMS without user data");
- }
- handled = true;
- }
-
- if (handled) {
- return Intents.RESULT_SMS_HANDLED;
- }
-
- if (SmsEnvelope.TELESERVICE_WAP == teleService) {
- return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
- sms.getOriginatingAddress());
- } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
- (SmsEnvelope.TELESERVICE_MWI == teleService)) {
+ if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
+ (SmsEnvelope.TELESERVICE_MWI == teleService)) {
// handling Voicemail
int voicemailCount = sms.getNumOfVoicemails();
Log.d(TAG, "Voicemail count=" + voicemailCount);
@@ -118,9 +104,30 @@
editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
editor.commit();
((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
+ handled = true;
+ } else if ((sms.getUserData() == null)) {
+ if (Config.LOGD) {
+ Log.d(TAG, "Received SMS without user data");
+ }
+ handled = true;
+ }
+
+ if (handled) {
return Intents.RESULT_SMS_HANDLED;
}
+ if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+ // It's a storable message and there's no storage available. Bail.
+ // (See C.S0015-B v2.0 for a description of "Immediate Display"
+ // messages, which we represent as CLASS_0.)
+ return Intents.RESULT_SMS_OUT_OF_MEMORY;
+ }
+
+ if (SmsEnvelope.TELESERVICE_WAP == teleService) {
+ return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
+ sms.getOriginatingAddress());
+ }
+
/**
* TODO(cleanup): Why are we using a getter method for this
* (and for so many other sms fields)? Trivial getters and
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 4c958f6..dab529e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -46,6 +46,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
@@ -443,6 +444,8 @@
if (!mIsMinInfoReady) {
mIsMinInfoReady = true;
}
+ phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
+ null);
} else {
Log.w(LOG_TAG,"error parsing cdmaSubscription params num="
+ cdmaSubscription.length);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index b412fec..0ca3148 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import static android.telephony.SmsMessage.MessageClass;
final class GsmSMSDispatcher extends SMSDispatcher {
private static final String TAG = "GSM";
@@ -111,6 +112,12 @@
return Intents.RESULT_SMS_HANDLED;
}
+ if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+ // It's a storable message and there's no storage available. Bail.
+ // (See TS 23.038 for a description of class 0 messages.)
+ return Intents.RESULT_SMS_OUT_OF_MEMORY;
+ }
+
SmsHeader smsHeader = sms.getUserDataHeader();
// See if message is partial or port addressed.
if ((smsHeader == null) || (smsHeader.concatRef == null)) {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 2eecef8..e4c8716 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -16,6 +16,7 @@
package com.android.dumprendertree;
+import com.android.dumprendertree.TestShellActivity.DumpDataType;
import com.android.dumprendertree.forwarder.AdbUtils;
import com.android.dumprendertree.forwarder.ForwardServer;
@@ -149,6 +150,8 @@
static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
+ static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
+ static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
private ForwardServer fs8000, fs8080, fs8443;
private MyTestRecorder mResultRecorder;
@@ -160,12 +163,7 @@
public LayoutTestsAutoTest() {
super("com.android.dumprendertree", TestShellActivity.class);
- int addr = -1;
- try {
- addr = AdbUtils.resolve("android-browser-test.mtv.corp.google.com");
- } catch (IOException ioe) {
- Log.e(LOGTAG, "failed to resolve server address.", ioe);
- }
+ int addr = getForwardHostAddr();
if(addr != -1) {
fs8000 = new ForwardServer(8000, addr, 8000);
fs8080 = new ForwardServer(8080, addr, 8080);
@@ -173,6 +171,38 @@
}
}
+ private int getForwardHostAddr() {
+ int addr = -1;
+ String host = null;
+ File forwardHostConf = new File(FORWARD_HOST_CONF);
+ if (forwardHostConf.isFile()) {
+ BufferedReader hostReader = null;
+ try {
+ hostReader = new BufferedReader(new FileReader(forwardHostConf));
+ host = hostReader.readLine();
+ Log.v(LOGTAG, "read forward host from file: " + host);
+ } catch (IOException ioe) {
+ Log.v(LOGTAG, "cannot read forward host from file", ioe);
+ } finally {
+ if (hostReader != null) {
+ try {
+ hostReader.close();
+ } catch (IOException ioe) {
+ // burn!!!
+ }
+ }
+ }
+ }
+ if (host == null || host.length() == 0)
+ host = DEFAULT_TEST_HOST;
+ try {
+ addr = AdbUtils.resolve(host);
+ } catch (IOException ioe) {
+ Log.e(LOGTAG, "failed to resolve server address", ioe);
+ }
+ return addr;
+ }
+
// This function writes the result of the layout test to
// Am status so that it can be picked up from a script.
private void passOrFailCallback(String file, boolean result) {
@@ -313,6 +343,7 @@
}
public void timedOut(String url) {
+ Log.v(LOGTAG, "layout timeout: " + url);
}
});
@@ -398,7 +429,8 @@
if (resume)
resumeTestList();
- TestShellActivity activity = (TestShellActivity) getActivity();
+ TestShellActivity activity = getActivity();
+ activity.setDefaultDumpDataType(DumpDataType.DUMP_AS_TEXT);
// Run tests.
int addr = -1;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 95a2384..f9d2434 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2364,13 +2364,12 @@
String8 region(config.string(), 2);
if (configSet.find(region) == configSet.end()) {
if (configSet.count(defaultLocale) == 0) {
- fprintf(stdout, "aapt: error: "
+ fprintf(stdout, "aapt: warning: "
"*** string '%s' has no default or required localization "
"for '%s' in %s\n",
String8(nameIter->first).string(),
config.string(),
mBundle->getResourceSourceDirs()[0]);
- err = UNKNOWN_ERROR;
}
}
}
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 6daa0d2..d4d2a45c 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -219,7 +219,12 @@
}
spanStack.pop();
- if (empty) {
+ /*
+ * This warning seems to be just an irritation to most people,
+ * since it is typically introduced by translators who then never
+ * see the warning.
+ */
+ if (0 && empty) {
fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
fileName, inXml->getLineNumber(),
String8(spanTag).string(), String8(*outString).string());