Merge "Add documentation to GridView."
diff --git a/Android.mk b/Android.mk
index ebc5213..08ee65e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -416,6 +416,8 @@
resources/samples/NotePad "Note Pad" \
-samplecode $(sample_dir)/SampleSyncAdapter \
resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
+ -samplecode frameworks/base/libs/rs/java \
+ resources/samples/Renderscript "Renderscript" \
-samplecode $(sample_dir)/SearchableDictionary \
resources/samples/SearchableDictionary "Searchable Dictionary v2" \
-samplecode $(sample_dir)/SipDemo \
@@ -429,13 +431,13 @@
-samplecode $(sample_dir)/SpinnerTest \
resources/samples/SpinnerTest "SpinnerTest" \
-samplecode $(sample_dir)/StackWidget \
- resources/samples/StackWidget "StackWidget" \
+ resources/samples/StackWidget "StackView Widget" \
-samplecode $(sample_dir)/TicTacToeLib \
resources/samples/TicTacToeLib "TicTacToeLib" \
-samplecode $(sample_dir)/TicTacToeMain \
resources/samples/TicTacToeMain "TicTacToeMain" \
-samplecode $(sample_dir)/WeatherListWidget \
- resources/samples/WeatherListWidget "Weather List Widget Sample" \
+ resources/samples/WeatherListWidget "Weather List Widget" \
-samplecode $(sample_dir)/Wiktionary \
resources/samples/Wiktionary "Wiktionary" \
-samplecode $(sample_dir)/WiktionarySimple \
diff --git a/api/11.xml b/api/11.xml
index 61472a3..76669e3 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -37266,17 +37266,6 @@
visibility="public"
>
</field>
-<field name="USES_POLICY_SETS_GLOBAL_PROXY"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="USES_POLICY_WATCH_LOGIN"
type="int"
transient="false"
@@ -37592,17 +37581,6 @@
visibility="public"
>
</method>
-<method name="getGlobalProxyAdmin"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getMaximumFailedPasswordsForWipe"
return="int"
abstract="false"
@@ -37887,23 +37865,6 @@
<parameter name="flags" type="int">
</parameter>
</method>
-<method name="setGlobalProxy"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="admin" type="android.content.ComponentName">
-</parameter>
-<parameter name="proxySpec" type="java.net.Proxy">
-</parameter>
-<parameter name="exclusionList" type="java.util.List<java.lang.String>">
-</parameter>
-</method>
<method name="setMaximumFailedPasswordsForWipe"
return="void"
abstract="false"
@@ -207497,22 +207458,22 @@
</method>
<method name="getDeviceId"
return="int"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getSource"
return="int"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
diff --git a/api/current.xml b/api/current.xml
index 7806c24..480ad93 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25064,6 +25064,17 @@
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
+<field name="MOVE_TASK_NO_USER_ACTION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="MOVE_TASK_WITH_HOME"
type="int"
transient="false"
@@ -25495,6 +25506,16 @@
visibility="public"
>
</field>
+<field name="persistentId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ActivityManager.RunningAppProcessInfo"
extends="java.lang.Object"
@@ -30692,6 +30713,19 @@
<parameter name="visibleCrumbs" type="int">
</parameter>
</method>
+<method name="setOnBreadCrumbClickListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.app.FragmentBreadCrumbs.OnBreadCrumbClickListener">
+</parameter>
+</method>
<method name="setParentTitle"
return="void"
abstract="false"
@@ -30725,6 +30759,29 @@
</parameter>
</method>
</class>
+<interface name="FragmentBreadCrumbs.OnBreadCrumbClickListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onBreadCrumbClick"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="backStack" type="android.app.FragmentManager.BackStackEntry">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</interface>
<class name="FragmentManager"
extends="java.lang.Object"
abstract="true"
@@ -37376,17 +37433,6 @@
visibility="public"
>
</field>
-<field name="USES_POLICY_SETS_GLOBAL_PROXY"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="USES_POLICY_WATCH_LOGIN"
type="int"
transient="false"
@@ -37702,17 +37748,6 @@
visibility="public"
>
</method>
-<method name="getGlobalProxyAdmin"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getMaximumFailedPasswordsForWipe"
return="int"
abstract="false"
@@ -37997,23 +38032,6 @@
<parameter name="flags" type="int">
</parameter>
</method>
-<method name="setGlobalProxy"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="admin" type="android.content.ComponentName">
-</parameter>
-<parameter name="proxySpec" type="java.net.Proxy">
-</parameter>
-<parameter name="exclusionList" type="java.util.List<java.lang.String>">
-</parameter>
-</method>
<method name="setMaximumFailedPasswordsForWipe"
return="void"
abstract="false"
@@ -76410,6 +76428,17 @@
<parameter name="offsetXY" type="int[]">
</parameter>
</method>
+<method name="getByteCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getConfig"
return="android.graphics.Bitmap.Config"
abstract="false"
@@ -94147,6 +94176,97 @@
>
</field>
</class>
+<class name="UsbAccessory"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getManufacturer"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getModel"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getType"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVersion"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parcel" 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>
+</class>
<class name="UsbConstants"
extends="java.lang.Object"
abstract="false"
@@ -95097,6 +95217,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="getAccessoryList"
+ return="android.hardware.UsbAccessory[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDeviceList"
return="java.util.HashMap<java.lang.String, android.hardware.UsbDevice>"
abstract="false"
@@ -95134,6 +95265,19 @@
<parameter name="function" type="java.lang.String">
</parameter>
</method>
+<method name="openAccessory"
+ return="android.os.ParcelFileDescriptor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accessory" type="android.hardware.UsbAccessory">
+</parameter>
+</method>
<method name="openDevice"
return="boolean"
abstract="false"
@@ -95147,6 +95291,28 @@
<parameter name="device" type="android.hardware.UsbDevice">
</parameter>
</method>
+<field name="ACTION_USB_ACCESSORY_ATTACHED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.action.USB_ACCESSORY_ATTACHED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_USB_ACCESSORY_DETACHED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.action.USB_ACCESSORY_DETACHED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_USB_DEVICE_ATTACHED"
type="java.lang.String"
transient="false"
@@ -95180,6 +95346,61 @@
visibility="public"
>
</field>
+<field name="EXTRA_ACCESSORY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_MANUFACTURER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-manufacturer""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_PRODUCT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-product""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-type""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_VERSION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-version""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="EXTRA_DEVICE"
type="java.lang.String"
transient="false"
@@ -95279,6 +95500,17 @@
visibility="public"
>
</field>
+<field name="USB_FUNCTION_ACCESSORY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USB_FUNCTION_ADB"
type="java.lang.String"
transient="false"
@@ -117430,7 +117662,7 @@
type="android.net.http.SslCertificate"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="issuedTo" type="java.lang.String">
@@ -118768,6 +119000,17 @@
visibility="public"
>
</method>
+<method name="getAuthUserName"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAutoRegistration"
return="boolean"
abstract="false"
@@ -118970,6 +119213,19 @@
visibility="public"
>
</method>
+<method name="setAuthUserName"
+ return="android.net.sip.SipProfile.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
<method name="setAutoRegistration"
return="android.net.sip.SipProfile.Builder"
abstract="false"
@@ -121010,6 +121266,17 @@
visibility="public"
>
</field>
+<field name="WIFI_MODE_FULL_HIGH_PERF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="WIFI_MODE_SCAN_ONLY"
type="int"
transient="false"
@@ -210389,6 +210656,17 @@
visibility="public"
>
</method>
+<method name="getMotionAxes"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getMotionRange"
return="android.view.InputDevice.MotionRange"
abstract="false"
@@ -210399,7 +210677,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="rangeType" type="int">
+<parameter name="axis" type="int">
</parameter>
</method>
<method name="getName"
@@ -210489,7 +210767,7 @@
value="8"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210500,7 +210778,7 @@
value="2"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210511,7 +210789,7 @@
value="3"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210522,7 +210800,7 @@
value="6"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210533,7 +210811,7 @@
value="7"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210544,7 +210822,7 @@
value="4"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210555,7 +210833,7 @@
value="5"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210566,7 +210844,7 @@
value="0"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210577,7 +210855,7 @@
value="1"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -210856,22 +211134,22 @@
</method>
<method name="getDeviceId"
return="int"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getSource"
return="int"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -211661,6 +211939,17 @@
<parameter name="c" type="int">
</parameter>
</method>
+<method name="getDeviceId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDisplayLabel"
return="char"
abstract="false"
@@ -211834,6 +212123,17 @@
visibility="public"
>
</method>
+<method name="getSource"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getUnicodeChar"
return="int"
abstract="false"
@@ -211937,6 +212237,19 @@
visibility="public"
>
</method>
+<method name="isGamepadButton"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
<method name="isLongPress"
return="boolean"
abstract="false"
@@ -212049,6 +212362,32 @@
visibility="public"
>
</method>
+<method name="keyCodeFromString"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="symbolicName" type="java.lang.String">
+</parameter>
+</method>
+<method name="keyCodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
<method name="metaStateHasModifiers"
return="boolean"
abstract="false"
@@ -212090,6 +212429,19 @@
<parameter name="metaState" type="int">
</parameter>
</method>
+<method name="setSource"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="int">
+</parameter>
+</method>
<method name="startTracking"
return="void"
abstract="false"
@@ -216300,6 +216652,32 @@
<parameter name="metaState" type="int">
</parameter>
</method>
+<method name="axisFromString"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="symbolicName" type="java.lang.String">
+</parameter>
+</method>
+<method name="axisToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+</method>
<method name="findPointerIndex"
return="int"
abstract="false"
@@ -216346,6 +216724,45 @@
visibility="public"
>
</method>
+<method name="getAxisValue"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+</method>
+<method name="getAxisValue"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+<parameter name="pointerIndex" type="int">
+</parameter>
+</method>
+<method name="getDeviceId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDownTime"
return="long"
abstract="false"
@@ -216390,6 +216807,38 @@
visibility="public"
>
</method>
+<method name="getHistoricalAxisValue"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+<parameter name="pos" type="int">
+</parameter>
+</method>
+<method name="getHistoricalAxisValue"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+<parameter name="pointerIndex" type="int">
+</parameter>
+<parameter name="pos" type="int">
+</parameter>
+</method>
<method name="getHistoricalEventTime"
return="long"
abstract="false"
@@ -216827,6 +217276,17 @@
<parameter name="pointerIndex" type="int">
</parameter>
</method>
+<method name="getSource"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getToolMajor"
return="float"
abstract="false"
@@ -217135,7 +217595,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="o" type="android.view.MotionEvent">
+<parameter name="other" type="android.view.MotionEvent">
</parameter>
</method>
<method name="obtainNoHistory"
@@ -217148,7 +217608,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="o" type="android.view.MotionEvent">
+<parameter name="other" type="android.view.MotionEvent">
</parameter>
</method>
<method name="offsetLocation"
@@ -217218,6 +217678,19 @@
<parameter name="y" type="float">
</parameter>
</method>
+<method name="setSource"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="int">
+</parameter>
+</method>
<method name="transform"
return="void"
abstract="false"
@@ -217268,6 +217741,17 @@
visibility="public"
>
</field>
+<field name="ACTION_HOVER_MOVE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_MASK"
type="int"
transient="false"
@@ -217444,6 +217928,391 @@
visibility="public"
>
</field>
+<field name="AXIS_GENERIC_1"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="32"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_10"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="41"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_11"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="42"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_12"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="43"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_13"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="44"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_14"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="45"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_15"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="46"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_16"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="47"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_2"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="33"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_3"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="34"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_4"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="35"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_5"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="36"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_6"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="37"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_7"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="38"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_8"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="39"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_9"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="40"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HAT_X"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="15"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HAT_Y"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HSCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_LTRIGGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_ORIENTATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_PRESSURE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RTRIGGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="18"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RX"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="13"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RZ"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_TOOL_MAJOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="6"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_TOOL_MINOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_TOUCH_MAJOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_TOUCH_MINOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_VSCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_X"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_Y"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_Z"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="CREATOR"
type="android.os.Parcelable.Creator"
transient="false"
@@ -217526,6 +218395,68 @@
visibility="public"
>
</constructor>
+<constructor name="MotionEvent.PointerCoords"
+ type="android.view.MotionEvent.PointerCoords"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="other" type="android.view.MotionEvent.PointerCoords">
+</parameter>
+</constructor>
+<method name="clear"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="copyFrom"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="other" type="android.view.MotionEvent.PointerCoords">
+</parameter>
+</method>
+<method name="getAxisValue"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+</method>
+<method name="setAxisValue"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+<parameter name="value" type="float">
+</parameter>
+</method>
<field name="orientation"
type="float"
transient="false"
@@ -219512,6 +220443,19 @@
<parameter name="focusableMode" type="int">
</parameter>
</method>
+<method name="addOnAttachStateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnAttachStateChangeListener">
+</parameter>
+</method>
<method name="addOnLayoutChangeListener"
return="void"
abstract="false"
@@ -222515,6 +223459,19 @@
<parameter name="action" type="java.lang.Runnable">
</parameter>
</method>
+<method name="removeOnAttachStateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnAttachStateChangeListener">
+</parameter>
+</method>
<method name="removeOnLayoutChangeListener"
return="void"
abstract="false"
@@ -224836,6 +225793,40 @@
>
</field>
</class>
+<interface name="View.OnAttachStateChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onViewAttachedToWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+</method>
+<method name="onViewDetachedFromWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+</method>
+</interface>
<interface name="View.OnClickListener"
abstract="true"
static="true"
@@ -237424,7 +238415,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="s" type="java.lang.String">
+<parameter name="key" type="java.lang.String">
</parameter>
</method>
<method name="describeContents"
@@ -237459,7 +238450,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="s" type="java.lang.String">
+<parameter name="key" type="java.lang.String">
</parameter>
</method>
<method name="getIconResId"
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index fa61b71..6172aab 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -212,4 +212,13 @@
// shouldn't reach here
return mLastKeyframe.getValue();
}
+
+ @Override
+ public String toString() {
+ String returnVal = " ";
+ for (int i = 0; i < mNumKeyframes; ++i) {
+ returnVal += mKeyframes.get(i).getValue() + " ";
+ }
+ return returnVal;
+ }
}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index d038cd6..b8a7cb2 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -394,4 +394,16 @@
final ObjectAnimator anim = (ObjectAnimator) super.clone();
return anim;
}
+
+ @Override
+ public String toString() {
+ String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " +
+ mTarget;
+ if (mValues != null) {
+ for (int i = 0; i < mValues.length; ++i) {
+ returnVal += "\n " + mValues[i].toString();
+ }
+ }
+ return returnVal;
+ }
}
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 0c30aad..6f91fc0 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -578,6 +578,11 @@
return mAnimatedValue;
}
+ @Override
+ public String toString() {
+ return mPropertyName + ": " + mKeyframeSet.toString();
+ }
+
/**
* Utility method to derive a setter/getter method name from a property name, where the
* prefix is typically "set" or "get" and the first letter of the property name is
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 5a8a74a..2e44d6d 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1207,4 +1207,15 @@
sPendingAnimations.get().clear();
sDelayedAnims.get().clear();
}
+
+ @Override
+ public String toString() {
+ String returnVal = "ValueAnimator@" + Integer.toHexString(hashCode());
+ if (mValues != null) {
+ for (int i = 0; i < mValues.length; ++i) {
+ returnVal += "\n " + mValues[i].toString();
+ }
+ }
+ return returnVal;
+ }
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b7b0ef58..67e4806 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -349,7 +349,7 @@
* section for more information on how the lifecycle of a process is tied
* to the activities it is hosting. Note that it is important to save
* persistent data in {@link #onPause} instead of {@link #onSaveInstanceState}
- * because the later is not part of the lifecycle callbacks, so will not
+ * because the latter is not part of the lifecycle callbacks, so will not
* be called in every situation as described in its documentation.</p>
*
* <p class="note">Be aware that these semantics will change slightly between
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d76b67d..a660076 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -112,6 +112,11 @@
public int id;
/**
+ * The true identifier of this task, valid even if it is not running.
+ */
+ public int persistentId;
+
+ /**
* The original Intent used to launch the task. You can use this
* Intent to re-launch the task (if it is no longer running) or bring
* the current task to the front.
@@ -127,14 +132,6 @@
public ComponentName origActivity;
/**
- * Thumbnail representation of the task's last state. Must
- * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
- * @hide -- this is not scalable, need to have a separate API to get
- * the bitmap.
- */
- public Bitmap thumbnail;
-
- /**
* Description of the task's last state.
*/
public CharSequence description;
@@ -148,6 +145,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
+ dest.writeInt(persistentId);
if (baseIntent != null) {
dest.writeInt(1);
baseIntent.writeToParcel(dest, 0);
@@ -155,29 +153,19 @@
dest.writeInt(0);
}
ComponentName.writeToParcel(origActivity, dest);
- if (thumbnail != null) {
- dest.writeInt(1);
- thumbnail.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
TextUtils.writeToParcel(description, dest,
Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
public void readFromParcel(Parcel source) {
id = source.readInt();
+ persistentId = source.readInt();
if (source.readInt() != 0) {
baseIntent = Intent.CREATOR.createFromParcel(source);
} else {
baseIntent = null;
}
origActivity = ComponentName.readFromParcel(source);
- if (source.readInt() != 0) {
- thumbnail = Bitmap.CREATOR.createFromParcel(source);
- } else {
- thumbnail = null;
- }
description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
}
@@ -401,6 +389,16 @@
return getRunningTasks(maxNum, 0, null);
}
+ /** @hide */
+ public Bitmap getTaskThumbnail(int id) throws SecurityException {
+ try {
+ return ActivityManagerNative.getDefault().getTaskThumbnail(id);
+ } catch (RemoteException e) {
+ // System dead, we will be dead too soon!
+ return null;
+ }
+ }
+
/**
* Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
* activity along with the task, so it is positioned immediately behind
@@ -409,6 +407,13 @@
public static final int MOVE_TASK_WITH_HOME = 0x00000001;
/**
+ * Flag for {@link #moveTaskToFront(int, int)}: don't count this as a
+ * user-instigated action, so the current activity will not receive a
+ * hint that the user is leaving.
+ */
+ public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002;
+
+ /**
* Ask that the task associated with a given task ID be moved to the
* front of the stack, so it is now visible to the user. Requires that
* the caller hold permission {@link android.Manifest.permission#REORDER_TASKS}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c095c06..d3d3792 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -442,6 +442,20 @@
return true;
}
+ case GET_TASK_THUMBNAIL_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int id = data.readInt();
+ Bitmap bm = getTaskThumbnail(id);
+ reply.writeNoException();
+ if (bm != null) {
+ reply.writeInt(1);
+ bm.writeToParcel(reply, 0);
+ } else {
+ reply.writeInt(0);
+ }
+ return true;
+ }
+
case GET_SERVICES_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int maxNum = data.readInt();
@@ -1816,6 +1830,21 @@
reply.recycle();
return list;
}
+ public Bitmap getTaskThumbnail(int id) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(id);
+ mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Bitmap bm = null;
+ if (reply.readInt() != 0) {
+ bm = Bitmap.CREATOR.createFromParcel(reply);
+ }
+ data.recycle();
+ reply.recycle();
+ return bm;
+ }
public List getServices(int maxNum, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index 3f045ac..df64035 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -50,6 +50,26 @@
/** Listener to inform when a parent entry is clicked */
private OnClickListener mParentClickListener;
+ private OnBreadCrumbClickListener mOnBreadCrumbClickListener;
+
+ /**
+ * Interface to intercept clicks on the bread crumbs.
+ */
+ public interface OnBreadCrumbClickListener {
+ /**
+ * Called when a bread crumb is clicked.
+ *
+ * @param backStack The BackStackEntry whose bread crumb was clicked.
+ * May be null, if this bread crumb is for the root of the back stack.
+ * @param flags Additional information about the entry. Currently
+ * always 0.
+ *
+ * @return Return true to consume this click. Return to false to allow
+ * the default action (popping back stack to this entry) to occur.
+ */
+ public boolean onBreadCrumbClick(BackStackEntry backStack, int flags);
+ }
+
public FragmentBreadCrumbs(Context context) {
this(context, null);
}
@@ -107,6 +127,16 @@
updateCrumbs();
}
+ /**
+ * Sets a listener for clicks on the bread crumbs. This will be called before
+ * the default click action is performed.
+ *
+ * @param listener The new listener to set. Replaces any existing listener.
+ */
+ public void setOnBreadCrumbClickListener(OnBreadCrumbClickListener listener) {
+ mOnBreadCrumbClickListener = listener;
+ }
+
private BackStackRecord createBackStackEntry(CharSequence title, CharSequence shortTitle) {
if (title == null) return null;
@@ -266,8 +296,18 @@
mParentClickListener.onClick(v);
}
} else {
- mActivity.getFragmentManager().popBackStack(bse.getId(),
- bse == mTopEntry? FragmentManager.POP_BACK_STACK_INCLUSIVE : 0);
+ if (mOnBreadCrumbClickListener != null) {
+ if (mOnBreadCrumbClickListener.onBreadCrumbClick(
+ bse == mTopEntry ? null : bse, 0)) {
+ return;
+ }
+ }
+ if (bse == mTopEntry) {
+ // Pop everything off the back stack.
+ mActivity.getFragmentManager().popBackStack();
+ } else {
+ mActivity.getFragmentManager().popBackStack(bse.getId(), 0);
+ }
}
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5d4380b..f42e8fb 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -133,6 +133,7 @@
IThumbnailReceiver receiver) throws RemoteException;
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags) throws RemoteException;
+ public Bitmap getTaskThumbnail(int taskId) throws RemoteException;
public List getServices(int maxNum, int flags) throws RemoteException;
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
throws RemoteException;
@@ -514,7 +515,7 @@
int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-
+ int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index ec4ec89..1c7eb98 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -109,6 +109,7 @@
*
* <p>To control this policy, the device admin must have a "set-global-proxy"
* tag in the "uses-policies" section of its meta-data.
+ * @hide
*/
public static final int USES_POLICY_SETS_GLOBAL_PROXY = 5;
@@ -363,7 +364,7 @@
* the given policy control. The possible policy identifier inputs are:
* {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
- * {@link #USES_POLICY_WIPE_DATA}, {@link #USES_POLICY_SETS_GLOBAL_PROXY},
+ * {@link #USES_POLICY_WIPE_DATA},
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE}.
*/
public boolean usesPolicy(int policyIdent) {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index eccd7c9..29f8caf 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -148,7 +148,7 @@
/**
* Action periodically sent to a device administrator when the device password
- * is expiring.
+ * is expiring.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_EXPIRE_PASSWORD} to receive
@@ -266,8 +266,8 @@
/**
* Called periodically when the password is about to expire or has expired. It will typically
- * be called on device boot, once per day before the password expires and at the time when it
- * expires.
+ * be called at these times: on device boot, once per day before the password expires,
+ * and at the time when the password expires.
*
* <p>If the password is not updated by the user, this method will continue to be called
* once per day until the password is changed or the device admin disables password expiration.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3f3aa74..440cb54 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -730,8 +730,10 @@
}
/**
- * Get the current password expiration timeout for the given admin or the aggregate
- * of all admins if admin is null.
+ * Get the password expiration timeout for the given admin. The expiration timeout is the
+ * recurring expiration timeout provided in the call to
+ * {@link #setPasswordExpirationTimeout(ComponentName, long)} for the given admin or the
+ * aggregate of all policy administrators if admin is null.
*
* @param admin The name of the admin component to check, or null to aggregate all admins.
* @return The timeout for the given admin or the minimum of all timeouts
@@ -749,7 +751,9 @@
/**
* Get the current password expiration time for the given admin or an aggregate of
- * all admins if admin is null.
+ * all admins if admin is null. If the password is expired, this will return the time since
+ * the password expired as a negative number. If admin is null, then a composite of all
+ * expiration timeouts is returned - which will be the minimum of all timeouts.
*
* @param admin The name of the admin component to check, or null to aggregate all admins.
* @return The password expiration time, in ms.
@@ -1028,6 +1032,7 @@
* @param exclusionList a list of domains to be excluded from the global proxy.
* @return returns null if the proxy was successfully set, or a {@link ComponentName}
* of the device admin that sets thew proxy otherwise.
+ * @hide
*/
public ComponentName setGlobalProxy(ComponentName admin, Proxy proxySpec,
List<String> exclusionList ) {
@@ -1080,6 +1085,7 @@
* Returns the component name setting the global proxy.
* @return ComponentName object of the device admin that set the global proxy, or
* null if no admin has set the proxy.
+ * @hide
*/
public ComponentName getGlobalProxyAdmin() {
if (mService != null) {
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 9808200..d70b3d3 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -32,7 +32,7 @@
*/
public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "WallpaperBackupHelper";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
// This path must match what the WallpaperManagerService uses
private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";
@@ -64,6 +64,10 @@
wpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth();
mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
+
+ if (DEBUG) {
+ Slog.d(TAG, "dmW=" + mDesiredMinWidth + " dmH=" + mDesiredMinHeight);
+ }
}
/**
@@ -94,7 +98,7 @@
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(STAGE_FILE, options);
- if (DEBUG) Slog.v(TAG, "Restoring wallpaper image w=" + options.outWidth
+ if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
+ " h=" + options.outHeight);
// how much does the image differ from our preference?
@@ -103,13 +107,13 @@
if (widthRatio > 0.8 && widthRatio < 1.25
&& heightRatio > 0.8 && heightRatio < 1.25) {
// sufficiently close to our resolution; go ahead and use it
- if (DEBUG) Slog.v(TAG, "wallpaper dimension match; using");
+ if (DEBUG) Slog.d(TAG, "wallpaper dimension match; using");
f.renameTo(new File(WALLPAPER_IMAGE));
// TODO: spin a service to copy the restored image to sd/usb storage,
// since it does not exist anywhere other than the private wallpaper
// file.
} else {
- if (DEBUG) Slog.v(TAG, "dimensions too far off: wr=" + widthRatio
+ if (DEBUG) Slog.d(TAG, "dimensions too far off: wr=" + widthRatio
+ " hr=" + heightRatio);
f.delete();
}
diff --git a/core/java/android/app/package.html b/core/java/android/app/package.html
index 5137600..f37f1dc 100644
--- a/core/java/android/app/package.html
+++ b/core/java/android/app/package.html
@@ -32,8 +32,9 @@
action bar.</p>
<p>For information about using some the classes in this package, see the following
-documents: <a href="{@docRoot}guide/topics/fundamentals/index.html">Application
-Fundamentals</a> (for activities, services, and fragments), <a
+documents: <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>, <a
+href="{@docRoot}guide/topics/fundamentals/services.html">Services</a>, <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>, <a
href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a>, <a
href="{@docRoot}guide/topics/ui/dialogs.html">Creating Dialogs</a>, and <a
href="{@docRoot}guide/topics/ui/notifiers/index.html">Notifying the User</a>.</p>
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 4656e15..1f4fe80 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1049,6 +1049,9 @@
} else if (profile == BluetoothProfile.A2DP) {
BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
return true;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
+ return true;
} else {
return false;
}
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 6ec347f..116a068 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -136,17 +136,17 @@
newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
int oldState =
- intent.getIntExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, 0);
+ intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
- if (oldState == BluetoothInputDevice.STATE_CONNECTED &&
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (oldState == BluetoothProfile.STATE_CONNECTED &&
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_INCOMING);
}
- if (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -194,7 +194,7 @@
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -286,7 +286,7 @@
sendMessage(DISCONNECT_A2DP_OUTGOING);
deferMessage(message);
break;
- } else if (mService.getInputDeviceState(mDevice) !=
+ } else if (mService.getInputDeviceConnectionState(mDevice) !=
BluetoothInputDevice.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_OUTGOING);
deferMessage(message);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index a70de59..df212a8 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,91 +27,88 @@
import java.util.ArrayList;
import java.util.List;
+
/**
- * Public API for controlling the Bluetooth HID (Input Device) Profile
+ * This class provides the public APIs to control the Bluetooth Input
+ * Device Profile.
*
- * BluetoothInputDevice is a proxy object used to make calls to Bluetooth Service
- * which handles the HID profile.
+ *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothInputDevice proxy object.
*
- * Creating a BluetoothInputDevice object will initiate a binding with the
- * Bluetooth service. Users of this object should call close() when they
- * are finished, so that this proxy object can unbind from the service.
- *
- * Currently the Bluetooth service runs in the system server and this
- * proxy object will be immediately bound to the service on construction.
- *
- * @hide
+ *<p>Each method is protected with its appropriate permission.
+ *@hide
*/
-public final class BluetoothInputDevice {
+public final class BluetoothInputDevice implements BluetoothProfile {
private static final String TAG = "BluetoothInputDevice";
private static final boolean DBG = false;
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.INPUT_DEVICE_STATE";
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_PREVIOUS_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.PREVIOUS_INPUT_DEVICE_STATE";
-
- /** Indicates the state of an input device has changed.
- * This intent will always contain EXTRA_INPUT_DEVICE_STATE,
- * EXTRA_PREVIOUS_INPUT_DEVICE_STATE and BluetoothDevice.EXTRA_DEVICE
- * extras.
+ /**
+ * Intent used to broadcast the change in connection state of the Input
+ * Device profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_INPUT_DEVICE_STATE_CHANGED =
- "android.bluetooth.inputdevice.action.INPUT_DEVICE_STATE_CHANGED";
-
- public static final int STATE_DISCONNECTED = 0;
- public static final int STATE_CONNECTING = 1;
- public static final int STATE_CONNECTED = 2;
- public static final int STATE_DISCONNECTING = 3;
-
- /**
- * Auto connection, incoming and outgoing connection are allowed at this
- * priority level.
- */
- public static final int PRIORITY_AUTO_CONNECT = 1000;
- /**
- * Incoming and outgoing connection are allowed at this priority level
- */
- public static final int PRIORITY_ON = 100;
- /**
- * Connections to the device are not allowed at this priority level.
- */
- public static final int PRIORITY_OFF = 0;
- /**
- * Default priority level when the device is unpaired.
- */
- public static final int PRIORITY_UNDEFINED = -1;
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
/**
* Return codes for the connect and disconnect Bluez / Dbus calls.
+ * @hide
*/
public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_SUCCESS = 5004;
- private final IBluetooth mService;
- private final Context mContext;
+ private ServiceListener mServiceListener;
+ private BluetoothAdapter mAdapter;
+ private IBluetooth mService;
/**
* Create a BluetoothInputDevice proxy object for interacting with the local
- * Bluetooth Service which handle the HID profile.
- * @param c Context
+ * Bluetooth Service which handles the InputDevice profile
+ *
*/
- public BluetoothInputDevice(Context c) {
- mContext = c;
-
+ /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+ mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
if (b != null) {
mService = IBluetooth.Stub.asInterface(b);
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
+ }
} else {
Log.w(TAG, "Bluetooth Service not available!");
@@ -121,130 +118,151 @@
}
}
- /** Initiate a connection to an Input device.
- *
- * This function returns false on error and true if the connection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when the
- * connection is completed.
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
+ /**
+ * {@inheritDoc}
+ * @hide
*/
- public boolean connectInputDevice(BluetoothDevice device) {
- if (DBG) log("connectInputDevice(" + device + ")");
- try {
- return mService.connectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public boolean connect(BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.connectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
- }
-
- /** Initiate disconnect from an Input Device.
- * This function return false on error and true if the disconnection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when
- * disconnect is completed.
- *
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
- */
- public boolean disconnectInputDevice(BluetoothDevice device) {
- if (DBG) log("disconnectInputDevice(" + device + ")");
- try {
- return mService.disconnectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
- }
- }
-
- /** Check if a specified InputDevice is connected.
- *
- * @param device Remote BT device.
- * @return True if connected , false otherwise and on error.
- * @hide
- */
- public boolean isInputDeviceConnected(BluetoothDevice device) {
- if (DBG) log("isInputDeviceConnected(" + device + ")");
- int state = getInputDeviceState(device);
- if (state == STATE_CONNECTED) return true;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
- /** Check if any Input Device is connected.
- *
- * @return List of devices, empty List on error.
+ /**
+ * {@inheritDoc}
* @hide
*/
- public List<BluetoothDevice> getConnectedInputDevices() {
- if (DBG) log("getConnectedInputDevices()");
- try {
- return mService.getConnectedInputDevices();
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return new ArrayList<BluetoothDevice>();
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.disconnectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
- }
-
- /** Get the state of an Input Device.
- *
- * @param device Remote BT device.
- * @return The current state of the Input Device
- * @hide
- */
- public int getInputDeviceState(BluetoothDevice device) {
- if (DBG) log("getInputDeviceState(" + device + ")");
- try {
- return mService.getInputDeviceState(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return STATE_DISCONNECTED;
- }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
- * Set priority of an input device.
- *
- * Priority is a non-negative integer. Priority can take the following
- * values:
- * {@link PRIORITY_ON}, {@link PRIORITY_OFF}, {@link PRIORITY_AUTO_CONNECT}
- *
- * @param device Paired device.
- * @param priority Integer priority
- * @return true if priority is set, false on error
+ * {@inheritDoc}
*/
- public boolean setInputDevicePriority(BluetoothDevice device, int priority) {
- if (DBG) log("setInputDevicePriority(" + device + ", " + priority + ")");
- try {
- return mService.setInputDevicePriority(device, priority);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (DBG) log("getConnectedDevices()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getConnectedInputDevices();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
}
/**
- * Get the priority associated with an Input Device.
- *
- * @param device Input Device
- * @return non-negative priority, or negative error code on error.
+ * {@inheritDoc}
*/
- public int getInputDevicePriority(BluetoothDevice device) {
- if (DBG) log("getInputDevicePriority(" + device + ")");
- try {
- return mService.getInputDevicePriority(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return PRIORITY_OFF;
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (DBG) log("getDevicesMatchingStates()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getInputDevicesMatchingConnectionStates(states);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getConnectionState(BluetoothDevice device) {
+ if (DBG) log("getState(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDeviceConnectionState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ public boolean setPriority(BluetoothDevice device, int priority) {
+ if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF &&
+ priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
+ }
+ try {
+ return mService.setInputDevicePriority(device, priority);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ public int getPriority(BluetoothDevice device) {
+ if (DBG) log("getPriority(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDevicePriority(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.PRIORITY_OFF;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.PRIORITY_OFF;
+ }
+
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
}
private static void log(String msg) {
- Log.d(TAG, msg);
+ Log.d(TAG, msg);
}
}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index ef80195d..1ffee72 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -62,6 +62,11 @@
* A2DP profile.
*/
public static final int A2DP = 2;
+ /**
+ * Input Device Profile
+ * @hide
+ */
+ public static final int INPUT_DEVICE = 3;
/**
* Default priority for devices that we try to auto-connect to and
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
index 3f36926..18060a0 100644
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ b/core/java/android/bluetooth/BluetoothProfileState.java
@@ -72,10 +72,10 @@
newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
- if (mProfile == HID && (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED)) {
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
+ if (mProfile == HID && (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -96,7 +96,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
context.registerReceiver(mBroadcastReceiver, filter);
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index f3e73cf..69fb06a 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -85,7 +85,8 @@
boolean connectInputDevice(in BluetoothDevice device);
boolean disconnectInputDevice(in BluetoothDevice device);
List<BluetoothDevice> getConnectedInputDevices();
- int getInputDeviceState(in BluetoothDevice device);
+ List<BluetoothDevice> getInputDevicesMatchingConnectionStates(in int[] states);
+ int getInputDeviceConnectionState(in BluetoothDevice device);
boolean setInputDevicePriority(in BluetoothDevice device, int priority);
int getInputDevicePriority(in BluetoothDevice device);
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 659b937..2cb8a86 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -237,10 +237,28 @@
private BroadcastReceiver mConnectivityIntentReceiver =
new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
- sendCheckAlarmsMessage();
+ final boolean wasConnected = mDataConnectionIsConnected;
+
+ // don't use the intent to figure out if network is connected, just check
+ // ConnectivityManager directly.
+ mDataConnectionIsConnected = readDataConnectionState();
+ if (mDataConnectionIsConnected) {
+ if (!wasConnected) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Reconnection detected: clearing all backoffs");
+ }
+ mSyncStorageEngine.clearAllBackoffs(mSyncQueue);
+ }
+ sendCheckAlarmsMessage();
+ }
}
};
+ private boolean readDataConnectionState() {
+ NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
+ return (networkInfo != null) && networkInfo.isConnected();
+ }
+
private BroadcastReceiver mShutdownIntentReceiver =
new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -1411,8 +1429,7 @@
// to have the most recent value used.
try {
waitUntilReadyToRun();
- NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
- mDataConnectionIsConnected = (networkInfo != null) && networkInfo.isConnected();
+ mDataConnectionIsConnected = readDataConnectionState();
mSyncManagerWakeLock.acquire();
// Always do this first so that we be sure that any periodic syncs that
// are ready to run have been converted into pending syncs. This allows the
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index c8ca6189..a1e174b 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -525,7 +525,7 @@
}
}
- public void clearAllBackoffs() {
+ public void clearAllBackoffs(SyncQueue syncQueue) {
boolean changed = false;
synchronized (mAuthorities) {
for (AccountInfo accountInfo : mAccounts.values()) {
@@ -541,6 +541,7 @@
}
authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+ syncQueue.onBackoffChanged(accountInfo.account, authorityInfo.authority, 0);
changed = true;
}
}
diff --git a/core/java/android/content/pm/package.html b/core/java/android/content/pm/package.html
index b18adb2..d55f0f7 100644
--- a/core/java/android/content/pm/package.html
+++ b/core/java/android/content/pm/package.html
@@ -5,7 +5,7 @@
permissions, services, signatures, and providers.</p>
<p>Most of the information about an application package is defined by its manifest file. For
more information, see the <a
-href="{@docRoot}guide/topics/manifest/guide/topics/manifest/manifest-intro.html">AndroidManifest.xml
-File</a> documentation.</p>
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml File</a>
+documentation.</p>
</BODY>
</HTML>
\ No newline at end of file
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index bfaeb82..3ffc714 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -133,6 +133,8 @@
result.getChars(0, result.length(), data, 0);
}
buffer.sizeCopied = result.length();
+ } else {
+ buffer.sizeCopied = 0;
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 891a5d9..2e43eef 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -2354,39 +2354,37 @@
* @return true if write-ahead-logging is set. false otherwise
*/
public boolean enableWriteAheadLogging() {
- // turn off WAL until lockingprotocolerror bug and diskIO bug are fixed
- return false;
-// // make sure the database is not READONLY. WAL doesn't make sense for readonly-databases.
-// if (isReadOnly()) {
-// return false;
-// }
-// // acquire lock - no that no other thread is enabling WAL at the same time
-// lock();
-// try {
-// if (mConnectionPool != null) {
-// // already enabled
-// return true;
-// }
-// if (mPath.equalsIgnoreCase(MEMORY_DB_PATH)) {
-// Log.i(TAG, "can't enable WAL for memory databases.");
-// return false;
-// }
-//
-// // make sure this database has NO attached databases because sqlite's write-ahead-logging
-// // doesn't work for databases with attached databases
-// if (mHasAttachedDbs) {
-// if (Log.isLoggable(TAG, Log.DEBUG)) {
-// Log.d(TAG,
-// "this database: " + mPath + " has attached databases. can't enable WAL.");
-// }
-// return false;
-// }
-// mConnectionPool = new DatabaseConnectionPool(this);
-// setJournalMode(mPath, "WAL");
-// return true;
-// } finally {
-// unlock();
-// }
+ // make sure the database is not READONLY. WAL doesn't make sense for readonly-databases.
+ if (isReadOnly()) {
+ return false;
+ }
+ // acquire lock - no that no other thread is enabling WAL at the same time
+ lock();
+ try {
+ if (mConnectionPool != null) {
+ // already enabled
+ return true;
+ }
+ if (mPath.equalsIgnoreCase(MEMORY_DB_PATH)) {
+ Log.i(TAG, "can't enable WAL for memory databases.");
+ return false;
+ }
+
+ // make sure this database has NO attached databases because sqlite's write-ahead-logging
+ // doesn't work for databases with attached databases
+ if (mHasAttachedDbs) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG,
+ "this database: " + mPath + " has attached databases. can't enable WAL.");
+ }
+ return false;
+ }
+ mConnectionPool = new DatabaseConnectionPool(this);
+ setJournalMode(mPath, "WAL");
+ return true;
+ } finally {
+ unlock();
+ }
}
/**
@@ -2394,20 +2392,19 @@
* @hide
*/
public void disableWriteAheadLogging() {
- return;
-// // grab database lock so that writeAheadLogging is not disabled from 2 different threads
-// // at the same time
-// lock();
-// try {
-// if (mConnectionPool == null) {
-// return; // already disabled
-// }
-// mConnectionPool.close();
-// setJournalMode(mPath, "TRUNCATE");
-// mConnectionPool = null;
-// } finally {
-// unlock();
-// }
+ // grab database lock so that writeAheadLogging is not disabled from 2 different threads
+ // at the same time
+ lock();
+ try {
+ if (mConnectionPool == null) {
+ return; // already disabled
+ }
+ mConnectionPool.close();
+ setJournalMode(mPath, "TRUNCATE");
+ mConnectionPool = null;
+ } finally {
+ unlock();
+ }
}
/* package */ SQLiteDatabase getDatabaseHandle(String sql) {
diff --git a/core/java/android/hardware/IUsbManager.aidl b/core/java/android/hardware/IUsbManager.aidl
index b50b6b9..6c99ab3 100644
--- a/core/java/android/hardware/IUsbManager.aidl
+++ b/core/java/android/hardware/IUsbManager.aidl
@@ -16,6 +16,7 @@
package android.hardware;
+import android.hardware.UsbAccessory;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -25,4 +26,6 @@
/* Returns a list of all currently attached USB devices */
void getDeviceList(out Bundle devices);
ParcelFileDescriptor openDevice(String deviceName);
+ UsbAccessory getCurrentAccessory();
+ ParcelFileDescriptor openAccessory();
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 1bd8ef5..dd4096b 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -380,6 +380,58 @@
/*-----------------------------------------------------------------------*/
+ private class SensorEventPool {
+ private final int mPoolSize;
+ private final SensorEvent mPool[];
+ private int mNumItemsInPool;
+
+ private SensorEvent createSensorEvent() {
+ // maximal size for all legacy events is 3
+ return new SensorEvent(3);
+ }
+
+ SensorEventPool(int poolSize) {
+ mPoolSize = poolSize;
+ mNumItemsInPool = poolSize;
+ mPool = new SensorEvent[poolSize];
+ }
+
+ SensorEvent getFromPool() {
+ SensorEvent t = null;
+ synchronized (this) {
+ if (mNumItemsInPool > 0) {
+ // remove the "top" item from the pool
+ final int index = mPoolSize - mNumItemsInPool;
+ t = mPool[index];
+ mPool[index] = null;
+ mNumItemsInPool--;
+ }
+ }
+ if (t == null) {
+ // the pool was empty or this item was removed from the pool for
+ // the first time. In any case, we need to create a new item.
+ t = createSensorEvent();
+ }
+ return t;
+ }
+
+ void returnToPool(SensorEvent t) {
+ synchronized (this) {
+ // is there space left in the pool?
+ if (mNumItemsInPool < mPoolSize) {
+ // if so, return the item to the pool
+ mNumItemsInPool++;
+ final int index = mPoolSize - mNumItemsInPool;
+ mPool[index] = t;
+ }
+ }
+ }
+ }
+
+ private static SensorEventPool sPool;
+
+ /*-----------------------------------------------------------------------*/
+
static private class SensorThread {
Thread mThread;
@@ -485,10 +537,9 @@
/*-----------------------------------------------------------------------*/
private class ListenerDelegate {
- final SensorEventListener mSensorEventListener;
+ private final SensorEventListener mSensorEventListener;
private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>();
private final Handler mHandler;
- private SensorEvent mValuesPool;
public SparseBooleanArray mSensors = new SparseBooleanArray();
public SparseBooleanArray mFirstEvent = new SparseBooleanArray();
public SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -527,40 +578,12 @@
}
mSensorEventListener.onSensorChanged(t);
- returnToPool(t);
+ sPool.returnToPool(t);
}
};
addSensor(sensor);
}
- protected SensorEvent createSensorEvent() {
- // maximal size for all legacy events is 3
- return new SensorEvent(3);
- }
-
- protected SensorEvent getFromPool() {
- SensorEvent t = null;
- synchronized (this) {
- // remove the array from the pool
- t = mValuesPool;
- mValuesPool = null;
- }
- if (t == null) {
- // the pool was empty, we need a new one
- t = createSensorEvent();
- }
- return t;
- }
-
- protected void returnToPool(SensorEvent t) {
- synchronized (this) {
- // put back the array into the pool
- if (mValuesPool == null) {
- mValuesPool = t;
- }
- }
- }
-
Object getListener() {
return mSensorEventListener;
}
@@ -582,7 +605,7 @@
}
void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) {
- SensorEvent t = getFromPool();
+ SensorEvent t = sPool.getFromPool();
final float[] v = t.values;
v[0] = values[0];
v[1] = values[1];
@@ -644,6 +667,7 @@
}
} while (i>0);
+ sPool = new SensorEventPool( sFullSensorsList.size()*2 );
sSensorThread = new SensorThread();
}
}
diff --git a/core/java/android/hardware/UsbAccessory.aidl b/core/java/android/hardware/UsbAccessory.aidl
new file mode 100644
index 0000000..97a777b
--- /dev/null
+++ b/core/java/android/hardware/UsbAccessory.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+parcelable UsbAccessory;
diff --git a/core/java/android/hardware/UsbAccessory.java b/core/java/android/hardware/UsbAccessory.java
new file mode 100644
index 0000000..71672fa
--- /dev/null
+++ b/core/java/android/hardware/UsbAccessory.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+/**
+ * A class representing a USB accessory.
+ */
+public final class UsbAccessory implements Parcelable {
+
+ private static final String TAG = "UsbAccessory";
+
+ private String mManufacturer;
+ private String mModel;
+ private String mType;
+ private String mVersion;
+
+ private UsbAccessory() {
+ }
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String manufacturer, String model, String type, String version) {
+ mManufacturer = manufacturer;
+ mModel = model;
+ mType = type;
+ mVersion = version;
+ }
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String[] strings) {
+ mManufacturer = strings[0];
+ mModel = strings[1];
+ mType = strings[2];
+ mVersion = strings[3];
+ }
+
+ /**
+ * Returns the manufacturer of the accessory.
+ *
+ * @return the accessory manufacturer
+ */
+ public String getManufacturer() {
+ return mManufacturer;
+ }
+
+ /**
+ * Returns the model name of the accessory.
+ *
+ * @return the accessory model
+ */
+ public String getModel() {
+ return mModel;
+ }
+
+ /**
+ * Returns the type of the accessory.
+ *
+ * @return the accessory type
+ */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the version of the accessory.
+ *
+ * @return the accessory version
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ @Override
+ public String toString() {
+ return "UsbAccessory[mManufacturer=" + mManufacturer +
+ ", mModel=" + mModel +
+ ", mType=" + mType +
+ ", mVersion=" + mVersion + "]";
+ }
+
+ public static final Parcelable.Creator<UsbAccessory> CREATOR =
+ new Parcelable.Creator<UsbAccessory>() {
+ public UsbAccessory createFromParcel(Parcel in) {
+ String manufacturer = in.readString();
+ String model = in.readString();
+ String type = in.readString();
+ String version = in.readString();
+ return new UsbAccessory(manufacturer, model, type, version);
+ }
+
+ public UsbAccessory[] newArray(int size) {
+ return new UsbAccessory[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mManufacturer);
+ parcel.writeString(mModel);
+ parcel.writeString(mType);
+ parcel.writeString(mVersion);
+ }
+}
diff --git a/core/java/android/hardware/UsbManager.java b/core/java/android/hardware/UsbManager.java
index 8fad210..0f616ff 100644
--- a/core/java/android/hardware/UsbManager.java
+++ b/core/java/android/hardware/UsbManager.java
@@ -24,6 +24,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
@@ -44,11 +45,14 @@
* Broadcast Action: A sticky broadcast for USB state change events when in device mode.
*
* This is a sticky broadcast for clients that includes USB connected/disconnected state,
- * the USB configuration that is currently set and a bundle containing name/value pairs
- * with the names of the functions and a value of either {@link #USB_FUNCTION_ENABLED}
- * or {@link #USB_FUNCTION_DISABLED}.
- * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE},
- * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}.
+ * <ul>
+ * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
+ * <li> {@link #USB_CONFIGURATION} a Bundle containing name/value pairs where the name
+ * is the name of a USB function and the value is either {@link #USB_FUNCTION_ENABLED}
+ * or {@link #USB_FUNCTION_DISABLED}. The possible function names include
+ * {@link #USB_FUNCTION_MASS_STORAGE}, {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS},
+ * {@link #USB_FUNCTION_MTP} and {@link #USB_FUNCTION_ACCESSORY}.
+ * </ul>
*/
public static final String ACTION_USB_STATE =
"android.hardware.action.USB_STATE";
@@ -57,6 +61,16 @@
* Broadcast Action: A broadcast for USB device attached event.
*
* This intent is sent when a USB device is attached to the USB bus when in host mode.
+ * <ul>
+ * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
+ * <li> {@link #EXTRA_VENDOR_ID} containing the device's vendor ID (Integer)
+ * <li> {@link #EXTRA_PRODUCT_ID} containing the device's product ID (Integer)
+ * <li> {@link #EXTRA_DEVICE_CLASS} } containing the device class (Integer)
+ * <li> {@link #EXTRA_DEVICE_SUBCLASS} containing the device subclass (Integer)
+ * <li> {@link #EXTRA_DEVICE_PROTOCOL} containing the device protocol (Integer)
+ * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
+ * for the attached device
+ * </ul>
*/
public static final String ACTION_USB_DEVICE_ATTACHED =
"android.hardware.action.USB_DEVICE_ATTACHED";
@@ -65,10 +79,41 @@
* Broadcast Action: A broadcast for USB device detached event.
*
* This intent is sent when a USB device is detached from the USB bus when in host mode.
+ * <ul>
+ * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
+ * </ul>
*/
public static final String ACTION_USB_DEVICE_DETACHED =
"android.hardware.action.USB_DEVICE_DETACHED";
+ /**
+ * Broadcast Action: A broadcast for USB accessory attached event.
+ *
+ * This intent is sent when a USB accessory is attached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY_MANUFACTURER} containing the accessory's manufacturer (String)
+ * <li> {@link #EXTRA_ACCESSORY_PRODUCT} containing the accessory's product name (String)
+ * <li> {@link #EXTRA_ACCESSORY_TYPE} containing the accessory's type (String)
+ * <li> {@link #EXTRA_ACCESSORY_VERSION} containing the accessory's version (String)
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * for the attached accessory
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_ATTACHED =
+ "android.hardware.action.USB_ACCESSORY_ATTACHED";
+
+ /**
+ * Broadcast Action: A broadcast for USB accessory detached event.
+ *
+ * This intent is sent when a USB accessory is detached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * for the attached accessory that was detached
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_DETACHED =
+ "android.hardware.action.USB_ACCESSORY_DETACHED";
+
/**
* Boolean extra indicating whether USB is connected or disconnected.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
@@ -106,14 +151,22 @@
public static final String USB_FUNCTION_MTP = "mtp";
/**
- * Value indicating that a USB function is enabled.
+ * Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*/
+ public static final String USB_FUNCTION_ACCESSORY = "accessory";
+
+ /**
+ * Value indicating that a USB function is enabled.
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
+ */
public static final String USB_FUNCTION_ENABLED = "enabled";
/**
* Value indicating that a USB function is disabled.
- * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
*/
public static final String USB_FUNCTION_DISABLED = "disabled";
@@ -158,8 +211,39 @@
* Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
* containing the UsbDevice object for the device.
*/
+
public static final String EXTRA_DEVICE = "device";
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the UsbAccessory object for the accessory.
+ */
+ public static final String EXTRA_ACCESSORY = "accessory";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's manufacturer name.
+ */
+ public static final String EXTRA_ACCESSORY_MANUFACTURER = "accessory-manufacturer";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's product name.
+ */
+ public static final String EXTRA_ACCESSORY_PRODUCT = "accessory-product";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's type.
+ */
+ public static final String EXTRA_ACCESSORY_TYPE = "accessory-type";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's version.
+ */
+ public static final String EXTRA_ACCESSORY_VERSION = "accessory-version";
+
private IUsbManager mService;
/**
@@ -214,6 +298,41 @@
}
}
+ /**
+ * Returns a list of currently attached USB accessories.
+ * (in the current implementation there can be at most one)
+ *
+ * @return list of USB accessories, or null if none are attached.
+ */
+ public UsbAccessory[] getAccessoryList() {
+ try {
+ UsbAccessory accessory = mService.getCurrentAccessory();
+ if (accessory == null) {
+ return null;
+ } else {
+ return new UsbAccessory[] { accessory };
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openAccessory" , e);
+ return null;
+ }
+ }
+
+ /**
+ * Opens a file descriptor for reading and writing data to the USB accessory.
+ *
+ * @param accessory the USB accessory to open
+ * @return file descriptor, or null if the accessor could not be opened.
+ */
+ public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
+ try {
+ return mService.openAccessory();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openAccessory" , e);
+ return null;
+ }
+ }
+
private static File getFunctionEnableFile(String function) {
return new File("/sys/class/usb_composite/" + function + "/enable");
}
@@ -245,4 +364,20 @@
return false;
}
}
+
+ /**
+ * Enables or disables a USB function.
+ *
+ * @hide
+ */
+ public static boolean setFunctionEnabled(String function, boolean enable) {
+ try {
+ FileOutputStream stream = new FileOutputStream(getFunctionEnableFile(function));
+ stream.write(enable ? '1' : '0');
+ stream.close();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
}
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index daa1c09..d0c77cf 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -70,15 +70,6 @@
mContext = context;
}
- /**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getDnsPropNames() {
- return new String[0];
- }
-
public boolean isPrivateDnsRouteSet() {
return mPrivateDnsRouteSet;
}
@@ -91,10 +82,6 @@
return mNetworkInfo;
}
- public int getDefaultGatewayAddr() {
- return 0;
- }
-
public boolean isDefaultRouteSet() {
return mDefaultRouteSet;
}
@@ -181,14 +168,6 @@
return true;
}
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
public void setDataEnable(boolean enabled) {
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 9ecd68c..e04964e 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -59,7 +59,6 @@
private ITelephony mPhoneService;
private String mApnType;
- private static String[] sDnsPropNames;
private NetworkInfo mNetworkInfo;
private boolean mTeardownRequested = false;
private Handler mTarget;
@@ -67,7 +66,6 @@
private LinkProperties mLinkProperties;
private LinkCapabilities mLinkCapabilities;
private boolean mPrivateDnsRouteSet = false;
- private int mDefaultGatewayAddr = 0;
private boolean mDefaultRouteSet = false;
// DEFAULT and HIPRI are the same connection. If we're one of these we need to check if
@@ -94,18 +92,6 @@
}
mPhoneService = null;
-
- sDnsPropNames = new String[] {
- "net.rmnet0.dns1",
- "net.rmnet0.dns2",
- "net.eth0.dns1",
- "net.eth0.dns2",
- "net.eth0.dns3",
- "net.eth0.dns4",
- "net.gprs.dns1",
- "net.gprs.dns2",
- "net.ppp0.dns1",
- "net.ppp0.dns2"};
}
/**
@@ -166,15 +152,6 @@
}
}
- /**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getDnsPropNames() {
- return sDnsPropNames;
- }
-
public boolean isPrivateDnsRouteSet() {
return mPrivateDnsRouteSet;
}
@@ -187,10 +164,6 @@
return mNetworkInfo;
}
- public int getDefaultGatewayAddr() {
- return mDefaultGatewayAddr;
- }
-
public boolean isDefaultRouteSet() {
return mDefaultRouteSet;
}
@@ -279,7 +252,6 @@
//if (DBG) log("clearing mInterfaceName for "+ mApnType +
// " as it DISCONNECTED");
//mInterfaceName = null;
- //mDefaultGatewayAddr = 0;
break;
case CONNECTING:
setDetailedState(DetailedState.CONNECTING, reason, apnName);
@@ -507,47 +479,6 @@
}
/**
- * Tells the phone sub-system that the caller wants to
- * begin using the named feature. The only supported features at
- * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data, and
- * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific.
- * specific, except that the value {@code -1}
- * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS},
- * the other possible return values are
- * <ul>
- * <li>{@code Phone.APN_ALREADY_ACTIVE}</li>
- * <li>{@code Phone.APN_REQUEST_STARTED}</li>
- * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li>
- * <li>{@code Phone.APN_REQUEST_FAILED}</li>
- * </ul>
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
- * Tells the phone sub-system that the caller is finished
- * using the named feature. The only supported feature at
- * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data.
- * @param feature the name of the feature that is no longer needed
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific, except that
- * the value {@code -1} always indicates failure.
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled) {
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index e378506..eb97d77 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -136,39 +136,6 @@
public boolean isAvailable();
/**
- * Fetch default gateway address for the network
- */
- public int getDefaultGatewayAddr();
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature that is no longer needed.
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled);
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 97f96da..b3f3988 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -159,17 +159,7 @@
*/
public static InetAddress numericToInetAddress(String addrString)
throws IllegalArgumentException {
- // TODO - do this for real, using a hidden method on InetAddress that aborts
- // instead of doing dns step
- if (!InetAddress.isNumeric(addrString)) {
- throw new IllegalArgumentException("numericToInetAddress with non numeric: '" +
- addrString + "'");
- }
- try {
- return InetAddress.getByName(addrString);
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException(e);
- }
+ return InetAddress.parseNumericAddress(addrString);
}
/**
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index d143243..eca06c5 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -69,6 +69,43 @@
public static native long getMobileRxBytes();
/**
+ * Get the total number of packets transmitted through the specified interface.
+ *
+ * @return number of packets. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getTxPackets(String iface);
+
+ /**
+ * Get the total number of packets received through the specified interface.
+ *
+ * @return number of packets. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getRxPackets(String iface);
+
+ /**
+ * Get the total number of bytes transmitted through the specified interface.
+ *
+ * @return number of bytes. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getTxBytes(String iface);
+
+ /**
+ * Get the total number of bytes received through the specified interface.
+ *
+ * @return number of bytes. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getRxBytes(String iface);
+
+
+ /**
* Get the total number of packets sent through all network interfaces.
*
* @return the number of packets. If the statistics are not supported by this device,
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index bba11b0..5079c23 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -110,7 +110,7 @@
* @param issuedBy The entity that issued this certificate
* @param validNotBefore The not-before date from the certificate validity period in ISO 8601 format
* @param validNotAfter The not-after date from the certificate validity period in ISO 8601 format
- * @deprecated Use {@link #SslCertificate(String, String, Date, Date)}
+ * @deprecated Use {@link #SslCertificate(X509Certificate)}
*/
@Deprecated
public SslCertificate(
@@ -124,7 +124,9 @@
* @param issuedBy The entity that issued this certificate
* @param validNotBefore The not-before date from the certificate validity period
* @param validNotAfter The not-after date from the certificate validity period
+ * @deprecated Use {@link #SslCertificate(X509Certificate)}
*/
+ @Deprecated
public SslCertificate(
String issuedTo, String issuedBy, Date validNotBefore, Date validNotAfter) {
mIssuedTo = new DName(issuedTo);
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 622bcdb..8c56fda 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -702,4 +702,28 @@
return null;
}
}
+
+ /**
+ * To change the Secure Element Card Emulation state (ON/OFF)
+ * @hide
+ */
+ public void changeNfcSecureElementCardEmulationState(boolean state)
+ {
+ int seId = 11259375;
+ if(state){
+ /* Enable card emulation */
+ try {
+ sService.selectSecureElement(seId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Enable card emulation failed", e);
+ }
+ }else{
+ /* Disable card emulation */
+ try {
+ sService.deselectSecureElement();
+ } catch (RemoteException e) {
+ Log.e(TAG, " card emulation failed", e);
+ }
+ }
+ }
}
diff --git a/core/java/android/nfc/tech/package.html b/core/java/android/nfc/tech/package.html
new file mode 100644
index 0000000..a99828f
--- /dev/null
+++ b/core/java/android/nfc/tech/package.html
@@ -0,0 +1,13 @@
+<HTML>
+<BODY>
+<p>
+These classes provide access to a tag technology's features, which vary by the type
+of tag that is scanned. A scanned tag can support multiple technologies, and you can find
+out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
+
+<p>For more information on dealing with tag technologies and handling the ones that you care about, see
+<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
+The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
+supported technologies.</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 6e6731e..90e2e79 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -23,6 +23,7 @@
import java.util.Map;
import android.content.pm.ApplicationInfo;
+import android.telephony.SignalStrength;
import android.util.Log;
import android.util.Printer;
import android.util.SparseArray;
@@ -608,18 +609,6 @@
* {@hide}
*/
public abstract long getPhoneOnTime(long batteryRealtime, int which);
-
- public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- public static final int SIGNAL_STRENGTH_POOR = 1;
- public static final int SIGNAL_STRENGTH_MODERATE = 2;
- public static final int SIGNAL_STRENGTH_GOOD = 3;
- public static final int SIGNAL_STRENGTH_GREAT = 4;
-
- static final String[] SIGNAL_STRENGTH_NAMES = {
- "none", "poor", "moderate", "good", "great"
- };
-
- public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
/**
* Returns the time in microseconds that the phone has been running with
@@ -710,7 +699,7 @@
SCREEN_BRIGHTNESS_NAMES),
new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
- SIGNAL_STRENGTH_NAMES),
+ SignalStrength.SIGNAL_STRENGTH_NAMES),
new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
new String[] {"in", "out", "emergency", "off"}),
@@ -1095,14 +1084,14 @@
dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
// Dump signal strength stats
- args = new Object[NUM_SIGNAL_STRENGTH_BINS];
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
}
dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthCount(i, which);
}
dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
@@ -1408,14 +1397,14 @@
sb.append(prefix);
sb.append(" Signal levels: ");
didOne = false;
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
if (time == 0) {
continue;
}
if (didOne) sb.append(", ");
didOne = true;
- sb.append(SIGNAL_STRENGTH_NAMES[i]);
+ sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
sb.append(" ");
formatTimeMs(sb, time/1000);
sb.append("(");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 257f275..f5cf76e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3704,7 +3704,6 @@
TTS_ENABLED_PLUGINS,
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
- WIFI_COUNTRY_CODE,
WIFI_NUM_OPEN_NETWORKS_KEPT,
MOUNT_PLAY_NOTIFICATION_SND,
MOUNT_UMS_AUTOSTART,
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 3316ea5..c0b3cc8 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -57,6 +57,7 @@
private final BluetoothService mBluetoothService;
private final BluetoothAdapter mAdapter;
private BluetoothA2dp mA2dp;
+ private BluetoothInputDevice mInputDevice;
private final Context mContext;
// The WakeLock is used for bringing up the LCD during a pairing request
// from remote device when Android is in Suspend state.
@@ -125,15 +126,24 @@
/*package*/ void getProfileProxy() {
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
+ mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
}
private BluetoothProfile.ServiceListener mProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mA2dp = (BluetoothA2dp) proxy;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = (BluetoothA2dp) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
}
public void onServiceDisconnected(int profile) {
- mA2dp = null;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -651,10 +661,9 @@
} else {
Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address);
}
- } else if (BluetoothUuid.isInputDevice(uuid) && !isOtherInputDeviceConnected(address)) {
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- authorized = inputDevice.getInputDevicePriority(device) >
- BluetoothInputDevice.PRIORITY_OFF;
+ } else if (mInputDevice != null && BluetoothUuid.isInputDevice(uuid)) {
+ // We can have more than 1 input device connected.
+ authorized = mInputDevice.getPriority(device) > BluetoothInputDevice.PRIORITY_OFF;
if (authorized) {
Log.i(TAG, "Allowing incoming HID connection from " + address);
} else {
@@ -669,18 +678,6 @@
return authorized;
}
- private boolean isOtherInputDeviceConnected(String address) {
- List<BluetoothDevice> devices =
- mBluetoothService.lookupInputDevicesMatchingStates(new int[] {
- BluetoothInputDevice.STATE_CONNECTING,
- BluetoothInputDevice.STATE_CONNECTED});
-
- for (BluetoothDevice device : devices) {
- if (!device.getAddress().equals(address)) return true;
- }
- return false;
- }
-
private boolean onAgentOutOfBandDataAvailable(String objectPath) {
if (!mBluetoothService.isEnabled()) return false;
@@ -758,7 +755,7 @@
boolean connected = false;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
- int state = mBluetoothService.getInputDeviceState(device);
+ int state = mBluetoothService.getInputDeviceConnectionState(device);
if (state == BluetoothInputDevice.STATE_CONNECTING) {
if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
connected = true;
diff --git a/core/java/android/server/BluetoothInputProfileHandler.java b/core/java/android/server/BluetoothInputProfileHandler.java
index 7ffa5ae..cdc0f2d 100644
--- a/core/java/android/server/BluetoothInputProfileHandler.java
+++ b/core/java/android/server/BluetoothInputProfileHandler.java
@@ -64,7 +64,7 @@
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
+ getInputDeviceConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_OFF) {
return false;
}
@@ -92,7 +92,7 @@
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
+ getInputDeviceConnectionState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
return false;
}
if (state != null) {
@@ -115,7 +115,7 @@
return true;
}
- synchronized int getInputDeviceState(BluetoothDevice device) {
+ synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
if (mInputDevices.get(device) == null) {
return BluetoothInputDevice.STATE_DISCONNECTED;
}
@@ -128,6 +128,11 @@
return devices;
}
+ synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(int[] states) {
+ List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(states);
+ return devices;
+ }
+
synchronized int getInputDevicePriority(BluetoothDevice device) {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
@@ -147,7 +152,7 @@
List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device: mInputDevices.keySet()) {
- int inputDeviceState = getInputDeviceState(device);
+ int inputDeviceState = getInputDeviceConnectionState(device);
for (int state : states) {
if (state == inputDeviceState) {
inputDevices.add(device);
@@ -178,10 +183,10 @@
setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_AUTO_CONNECT);
}
- Intent intent = new Intent(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, prevState);
- intent.putExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, state);
+ intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothInputDevice.EXTRA_STATE, state);
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index a295de5..70aaf0a 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -31,6 +31,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDeviceProfileState;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfileState;
@@ -83,6 +84,7 @@
private int mNativeData;
private BluetoothEventLoop mEventLoop;
private BluetoothHeadset mBluetoothHeadset;
+ private BluetoothInputDevice mInputDevice;
private boolean mIsAirplaneSensitive;
private boolean mIsAirplaneToggleable;
private int mBluetoothState;
@@ -2078,6 +2080,8 @@
mAdapter.getProfileProxy(mContext,
mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
+ mAdapter.getProfileProxy(mContext,
+ mBluetoothProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
pw.println("\n--Known devices--");
for (String address : mDeviceProperties.keySet()) {
@@ -2119,8 +2123,17 @@
}
}
- // Rather not do this from here, but no-where else and I need this
- // dump
+ dumpHeadsetProfile(pw);
+ dumpInputDeviceProfile(pw);
+
+ pw.println("\n--Application Service Records--");
+ for (Integer handle : mServiceRecordToPid.keySet()) {
+ Integer pid = mServiceRecordToPid.get(handle);
+ pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ }
+ }
+
+ private void dumpHeadsetProfile(PrintWriter pw) {
pw.println("\n--Headset Service--");
if (mBluetoothHeadset != null) {
List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
@@ -2158,24 +2171,60 @@
pw.println("SCO audio connected to device:" + device);
}
}
-
- mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
}
+ mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+ }
- pw.println("\n--Application Service Records--");
- for (Integer handle : mServiceRecordToPid.keySet()) {
- Integer pid = mServiceRecordToPid.get(handle);
- pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ private void dumpInputDeviceProfile(PrintWriter pw) {
+ pw.println("\n--Bluetooth Service- Input Device Profile");
+ if (mInputDevice != null) {
+ List<BluetoothDevice> deviceList = mInputDevice.getConnectedDevices();
+ if (deviceList.size() == 0) {
+ pw.println("\nNo input devices connected--");
+ } else {
+ pw.println("\nNumber of connected devices:" + deviceList.size());
+ BluetoothDevice device = deviceList.get(0);
+ pw.println("getConnectedDevices[0] = " + device);
+ pw.println("Priority of Connected device = " + mInputDevice.getPriority(device));
+
+ switch (mInputDevice.getConnectionState(device)) {
+ case BluetoothInputDevice.STATE_CONNECTING:
+ pw.println("getConnectionState() = STATE_CONNECTING");
+ break;
+ case BluetoothInputDevice.STATE_CONNECTED:
+ pw.println("getConnectionState() = STATE_CONNECTED");
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ pw.println("getConnectionState() = STATE_DISCONNECTING");
+ break;
+ }
+ }
+ deviceList.clear();
+ deviceList = mInputDevice.getDevicesMatchingConnectionStates(new int[] {
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
+ pw.println("--Connected and Disconnected input devices");
+ for (BluetoothDevice device: deviceList) {
+ pw.println(device);
+ }
}
+ mAdapter.closeProfileProxy(BluetoothProfile.INPUT_DEVICE, mBluetoothHeadset);
}
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mBluetoothHeadset = (BluetoothHeadset) proxy;
- }
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = (BluetoothHeadset) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
+ }
public void onServiceDisconnected(int profile) {
- mBluetoothHeadset = null;
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -2311,9 +2360,9 @@
return mBluetoothInputProfileHandler.disconnectInputDeviceInternal(device);
}
- public synchronized int getInputDeviceState(BluetoothDevice device) {
+ public synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return mBluetoothInputProfileHandler.getInputDeviceState(device);
+ return mBluetoothInputProfileHandler.getInputDeviceConnectionState(device);
}
@@ -2322,6 +2371,13 @@
return mBluetoothInputProfileHandler.getConnectedInputDevices();
}
+ public synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(
+ int[] states) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mBluetoothInputProfileHandler.getInputDevicesMatchingConnectionStates(states);
+ }
+
+
public synchronized int getInputDevicePriority(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mBluetoothInputProfileHandler.getInputDevicePriority(device);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 8700af8..97a216a 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -600,8 +600,9 @@
* are at different run levels (and thus there's a split caret).
* @param offset the offset
* @return true if at a level boundary
+ * @hide
*/
- private boolean isLevelBoundary(int offset) {
+ public boolean isLevelBoundary(int offset) {
int line = getLineForOffset(offset);
Directions dirs = getLineDirections(line);
if (dirs == DIRS_ALL_LEFT_TO_RIGHT || dirs == DIRS_ALL_RIGHT_TO_LEFT) {
@@ -1148,8 +1149,7 @@
int bottom = getLineTop(line+1);
float h1 = getPrimaryHorizontal(point) - 0.5f;
- float h2 = isLevelBoundary(point) ?
- getSecondaryHorizontal(point) - 0.5f : h1;
+ float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point) - 0.5f : h1;
int caps = TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SHIFT_ON) |
TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SELECTING);
diff --git a/core/java/android/text/SpannableStringInternal.java b/core/java/android/text/SpannableStringInternal.java
index 0412285..0825bf3 100644
--- a/core/java/android/text/SpannableStringInternal.java
+++ b/core/java/android/text/SpannableStringInternal.java
@@ -212,6 +212,10 @@
Object ret1 = null;
for (int i = 0; i < spanCount; i++) {
+ if (kind != null && !kind.isInstance(spans[i])) {
+ continue;
+ }
+
int spanStart = data[i * COLUMNS + START];
int spanEnd = data[i * COLUMNS + END];
@@ -231,10 +235,6 @@
}
}
- if (kind != null && !kind.isInstance(spans[i])) {
- continue;
- }
-
if (count == 0) {
ret1 = spans[i];
count++;
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index ac3df79..a4546f0 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -36,8 +36,8 @@
* float, float, android.graphics.Paint)
* Canvas.drawText()} directly.</p>
*/
-public class StaticLayout extends Layout
-{
+public class StaticLayout extends Layout {
+
public StaticLayout(CharSequence source, TextPaint paint,
int width,
Alignment align, float spacingmult, float spacingadd,
@@ -114,8 +114,8 @@
mMeasured = MeasuredText.obtain();
}
- /* package */ void generate(CharSequence source, int bufstart, int bufend,
- TextPaint paint, int outerwidth,
+ /* package */ void generate(CharSequence source, int bufStart, int bufEnd,
+ TextPaint paint, int outerWidth,
Alignment align,
float spacingmult, float spacingadd,
boolean includepad, boolean trackpad,
@@ -126,7 +126,7 @@
boolean needMultiply = (spacingmult != 1 || spacingadd != 0);
Paint.FontMetricsInt fm = mFontMetricsInt;
- int[] choosehtv = null;
+ int[] chooseHtv = null;
MeasuredText measured = mMeasured;
@@ -137,27 +137,26 @@
int DEFAULT_DIR = DIR_LEFT_TO_RIGHT; // XXX
int paraEnd;
- for (int paraStart = bufstart; paraStart <= bufend; paraStart = paraEnd) {
- paraEnd = TextUtils.indexOf(source, '\n', paraStart, bufend);
+ for (int paraStart = bufStart; paraStart <= bufEnd; paraStart = paraEnd) {
+ paraEnd = TextUtils.indexOf(source, CHAR_NEW_LINE, paraStart, bufEnd);
if (paraEnd < 0)
- paraEnd = bufend;
+ paraEnd = bufEnd;
else
paraEnd++;
- int paraLen = paraEnd - paraStart;
int firstWidthLineLimit = mLineCount + 1;
- int firstwidth = outerwidth;
- int restwidth = outerwidth;
+ int firstWidth = outerWidth;
+ int restWidth = outerWidth;
- LineHeightSpan[] chooseht = null;
+ LineHeightSpan[] chooseHt = null;
if (spanned != null) {
LeadingMarginSpan[] sp = getParagraphSpans(spanned, paraStart, paraEnd,
LeadingMarginSpan.class);
for (int i = 0; i < sp.length; i++) {
LeadingMarginSpan lms = sp[i];
- firstwidth -= sp[i].getLeadingMargin(true);
- restwidth -= sp[i].getLeadingMargin(false);
+ firstWidth -= sp[i].getLeadingMargin(true);
+ restWidth -= sp[i].getLeadingMargin(false);
// LeadingMarginSpan2 is odd. The count affects all
// leading margin spans, not just this particular one,
@@ -166,32 +165,31 @@
if (lms instanceof LeadingMarginSpan2) {
LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms;
int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2));
- firstWidthLineLimit = lmsFirstLine +
- lms2.getLeadingMarginLineCount();
+ firstWidthLineLimit = lmsFirstLine + lms2.getLeadingMarginLineCount();
}
}
- chooseht = getParagraphSpans(spanned, paraStart, paraEnd, LineHeightSpan.class);
+ chooseHt = getParagraphSpans(spanned, paraStart, paraEnd, LineHeightSpan.class);
- if (chooseht.length != 0) {
- if (choosehtv == null ||
- choosehtv.length < chooseht.length) {
- choosehtv = new int[ArrayUtils.idealIntArraySize(
- chooseht.length)];
+ if (chooseHt.length != 0) {
+ if (chooseHtv == null ||
+ chooseHtv.length < chooseHt.length) {
+ chooseHtv = new int[ArrayUtils.idealIntArraySize(
+ chooseHt.length)];
}
- for (int i = 0; i < chooseht.length; i++) {
- int o = spanned.getSpanStart(chooseht[i]);
+ for (int i = 0; i < chooseHt.length; i++) {
+ int o = spanned.getSpanStart(chooseHt[i]);
if (o < paraStart) {
// starts in this layout, before the
// current paragraph
- choosehtv[i] = getLineTop(getLineForOffset(o));
+ chooseHtv[i] = getLineTop(getLineForOffset(o));
} else {
// starts in this paragraph
- choosehtv[i] = v;
+ chooseHtv[i] = v;
}
}
}
@@ -204,20 +202,18 @@
int dir = measured.mDir;
boolean easy = measured.mEasy;
- CharSequence sub = source;
-
- int width = firstwidth;
+ int width = firstWidth;
float w = 0;
int here = paraStart;
int ok = paraStart;
- float okwidth = w;
- int okascent = 0, okdescent = 0, oktop = 0, okbottom = 0;
+ float okWidth = w;
+ int okAscent = 0, okDescent = 0, okTop = 0, okBottom = 0;
int fit = paraStart;
- float fitwidth = w;
- int fitascent = 0, fitdescent = 0, fittop = 0, fitbottom = 0;
+ float fitWidth = w;
+ int fitAscent = 0, fitDescent = 0, fitTop = 0, fitBottom = 0;
boolean hasTabOrEmoji = false;
boolean hasTab = false;
@@ -244,21 +240,18 @@
}
nextSpanStart = spanEnd;
- int startInPara = spanStart - paraStart;
- int endInPara = spanEnd - paraStart;
- int fmtop = fm.top;
- int fmbottom = fm.bottom;
- int fmascent = fm.ascent;
- int fmdescent = fm.descent;
+ int fmTop = fm.top;
+ int fmBottom = fm.bottom;
+ int fmAscent = fm.ascent;
+ int fmDescent = fm.descent;
for (int j = spanStart; j < spanEnd; j++) {
char c = chs[j - paraStart];
- float before = w;
- if (c == '\n') {
+ if (c == CHAR_NEW_LINE) {
// intentionally left empty
- } else if (c == '\t') {
+ } else if (c == CHAR_TAB) {
if (hasTab == false) {
hasTab = true;
hasTabOrEmoji = true;
@@ -276,7 +269,8 @@
} else {
w = TabStops.nextDefaultStop(w, TAB_INCREMENT);
}
- } else if (c >= 0xD800 && c <= 0xDFFF && j + 1 < spanEnd) {
+ } else if (c >= CHAR_FIRST_HIGH_SURROGATE && c <= CHAR_LAST_LOW_SURROGATE
+ && j + 1 < spanEnd) {
int emoji = Character.codePointAt(chs, j - paraStart);
if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) {
@@ -311,17 +305,17 @@
// Log.e("text", "was " + before + " now " + w + " after " + c + " within " + width);
if (w <= width) {
- fitwidth = w;
+ fitWidth = w;
fit = j + 1;
- if (fmtop < fittop)
- fittop = fmtop;
- if (fmascent < fitascent)
- fitascent = fmascent;
- if (fmdescent > fitdescent)
- fitdescent = fmdescent;
- if (fmbottom > fitbottom)
- fitbottom = fmbottom;
+ if (fmTop < fitTop)
+ fitTop = fmTop;
+ if (fmAscent < fitAscent)
+ fitAscent = fmAscent;
+ if (fmDescent > fitDescent)
+ fitDescent = fmDescent;
+ if (fmBottom > fitBottom)
+ fitBottom = fmBottom;
/*
* From the Unicode Line Breaking Algorithm:
@@ -339,25 +333,26 @@
* after but not before.
*/
- if (c == ' ' || c == '\t' ||
- ((c == '.' || c == ',' || c == ':' || c == ';') &&
+ if (c == CHAR_SPACE || c == CHAR_TAB ||
+ ((c == CHAR_DOT || c == CHAR_COMMA ||
+ c == CHAR_COLON || c == CHAR_SEMICOLON) &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - paraStart])) &&
(j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
- ((c == '/' || c == '-') &&
+ ((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
(j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
- (c >= FIRST_CJK && isIdeographic(c, true) &&
+ (c >= CHAR_FIRST_CJK && isIdeographic(c, true) &&
j + 1 < spanEnd && isIdeographic(chs[j + 1 - paraStart], false))) {
- okwidth = w;
+ okWidth = w;
ok = j + 1;
- if (fittop < oktop)
- oktop = fittop;
- if (fitascent < okascent)
- okascent = fitascent;
- if (fitdescent > okdescent)
- okdescent = fitdescent;
- if (fitbottom > okbottom)
- okbottom = fitbottom;
+ if (fitTop < okTop)
+ okTop = fitTop;
+ if (fitAscent < okAscent)
+ okAscent = fitAscent;
+ if (fitDescent > okDescent)
+ okDescent = fitDescent;
+ if (fitBottom > okBottom)
+ okBottom = fitBottom;
}
} else {
if (ellipsize != null) {
@@ -365,56 +360,56 @@
if (ok != here) {
// Log.e("text", "output ok " + here + " to " +ok);
- while (ok < spanEnd && chs[ok - paraStart] == ' ') {
+ while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
ok++;
}
v = out(source,
here, ok,
- okascent, okdescent, oktop, okbottom,
+ okAscent, okDescent, okTop, okBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- ok == bufend, includepad, trackpad,
+ ok == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, okwidth,
+ ellipsize, ellipsizedWidth, okWidth,
paint);
here = ok;
} else {
// Act like it fit even though it didn't.
- fitwidth = w;
+ fitWidth = w;
here = fit = j + 1;
- if (fmtop < fittop)
- fittop = fmtop;
- if (fmascent < fitascent)
- fitascent = fmascent;
- if (fmdescent > fitdescent)
- fitdescent = fmdescent;
- if (fmbottom > fitbottom)
- fitbottom = fmbottom;
+ if (fmTop < fitTop)
+ fitTop = fmTop;
+ if (fmAscent < fitAscent)
+ fitAscent = fmAscent;
+ if (fmDescent > fitDescent)
+ fitDescent = fmDescent;
+ if (fmBottom > fitBottom)
+ fitBottom = fmBottom;
}
} else {
if (ok != here) {
// Log.e("text", "output ok " + here + " to " +ok);
- while (ok < spanEnd && chs[ok - paraStart] == ' ') {
+ while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
ok++;
}
v = out(source,
here, ok,
- okascent, okdescent, oktop, okbottom,
+ okAscent, okDescent, okTop, okBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- ok == bufend, includepad, trackpad,
+ ok == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, okwidth,
+ ellipsize, ellipsizedWidth, okWidth,
paint);
here = ok;
@@ -422,15 +417,15 @@
// Log.e("text", "output fit " + here + " to " +fit);
v = out(source,
here, fit,
- fitascent, fitdescent,
- fittop, fitbottom,
+ fitAscent, fitDescent,
+ fitTop, fitBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- fit == bufend, includepad, trackpad,
+ fit == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, fitwidth,
+ ellipsize, ellipsizedWidth, fitWidth,
paint);
here = fit;
@@ -446,10 +441,10 @@
fm.ascent, fm.descent,
fm.top, fm.bottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- here + 1 == bufend, includepad,
+ here + 1 == bufEnd, includepad,
trackpad,
chs, widths, here - paraStart,
ellipsize, ellipsizedWidth,
@@ -470,65 +465,64 @@
ok = fit = here;
w = 0;
- fitascent = fitdescent = fittop = fitbottom = 0;
- okascent = okdescent = oktop = okbottom = 0;
+ fitAscent = fitDescent = fitTop = fitBottom = 0;
+ okAscent = okDescent = okTop = okBottom = 0;
if (--firstWidthLineLimit <= 0) {
- width = restwidth;
+ width = restWidth;
}
}
}
}
if (paraEnd != here) {
- if ((fittop | fitbottom | fitdescent | fitascent) == 0) {
+ if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
paint.getFontMetricsInt(fm);
- fittop = fm.top;
- fitbottom = fm.bottom;
- fitascent = fm.ascent;
- fitdescent = fm.descent;
+ fitTop = fm.top;
+ fitBottom = fm.bottom;
+ fitAscent = fm.ascent;
+ fitDescent = fm.descent;
}
// Log.e("text", "output rest " + here + " to " + end);
v = out(source,
- here, paraEnd, fitascent, fitdescent,
- fittop, fitbottom,
+ here, paraEnd, fitAscent, fitDescent,
+ fitTop, fitBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- paraEnd == bufend, includepad, trackpad,
+ paraEnd == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
ellipsize, ellipsizedWidth, w, paint);
}
paraStart = paraEnd;
- if (paraEnd == bufend)
+ if (paraEnd == bufEnd)
break;
}
- if (bufend == bufstart || source.charAt(bufend - 1) == '\n') {
- // Log.e("text", "output last " + bufend);
+ if (bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) {
+ // Log.e("text", "output last " + bufEnd);
paint.getFontMetricsInt(fm);
v = out(source,
- bufend, bufend, fm.ascent, fm.descent,
+ bufEnd, bufEnd, fm.ascent, fm.descent,
fm.top, fm.bottom,
v,
spacingmult, spacingadd, null,
null, fm, false,
- needMultiply, bufend, null, DEFAULT_DIR, true,
+ needMultiply, bufEnd, null, DEFAULT_DIR, true,
true, includepad, trackpad,
- null, null, bufstart,
+ null, null, bufStart,
ellipsize, ellipsizedWidth, 0, paint);
}
}
- private static final char FIRST_CJK = '\u2E80';
/**
* Returns true if the specified character is one of those specified
* as being Ideographic (class ID) by the Unicode Line Breaking Algorithm
@@ -636,14 +630,14 @@
private int out(CharSequence text, int start, int end,
int above, int below, int top, int bottom, int v,
float spacingmult, float spacingadd,
- LineHeightSpan[] chooseht, int[] choosehtv,
+ LineHeightSpan[] chooseHt, int[] chooseHtv,
Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
boolean needMultiply, int pstart, byte[] chdirs,
int dir, boolean easy, boolean last,
- boolean includepad, boolean trackpad,
- char[] chs, float[] widths, int widstart,
- TextUtils.TruncateAt ellipsize, float ellipsiswidth,
- float textwidth, TextPaint paint) {
+ boolean includePad, boolean trackPad,
+ char[] chs, float[] widths, int widthStart,
+ TextUtils.TruncateAt ellipsize, float ellipsisWidth,
+ float textWidth, TextPaint paint) {
int j = mLineCount;
int off = j * mColumns;
int want = off + mColumns + TOP;
@@ -662,19 +656,19 @@
mLineDirections = grow2;
}
- if (chooseht != null) {
+ if (chooseHt != null) {
fm.ascent = above;
fm.descent = below;
fm.top = top;
fm.bottom = bottom;
- for (int i = 0; i < chooseht.length; i++) {
- if (chooseht[i] instanceof LineHeightSpan.WithDensity) {
- ((LineHeightSpan.WithDensity) chooseht[i]).
- chooseHeight(text, start, end, choosehtv[i], v, fm, paint);
+ for (int i = 0; i < chooseHt.length; i++) {
+ if (chooseHt[i] instanceof LineHeightSpan.WithDensity) {
+ ((LineHeightSpan.WithDensity) chooseHt[i]).
+ chooseHeight(text, start, end, chooseHtv[i], v, fm, paint);
} else {
- chooseht[i].chooseHeight(text, start, end, choosehtv[i], v, fm);
+ chooseHt[i].chooseHeight(text, start, end, chooseHtv[i], v, fm);
}
}
@@ -685,20 +679,20 @@
}
if (j == 0) {
- if (trackpad) {
+ if (trackPad) {
mTopPadding = top - above;
}
- if (includepad) {
+ if (includePad) {
above = top;
}
}
if (last) {
- if (trackpad) {
+ if (trackPad) {
mBottomPadding = bottom - below;
}
- if (includepad) {
+ if (includePad) {
below = bottom;
}
}
@@ -708,9 +702,9 @@
if (needMultiply) {
double ex = (below - above) * (spacingmult - 1) + spacingadd;
if (ex >= 0) {
- extra = (int)(ex + 0.5);
+ extra = (int)(ex + EXTRA_ROUNDING);
} else {
- extra = -(int)(-ex + 0.5);
+ extra = -(int)(-ex + EXTRA_ROUNDING);
}
} else {
extra = 0;
@@ -735,45 +729,45 @@
if (easy) {
mLineDirections[j] = linedirs;
} else {
- mLineDirections[j] = AndroidBidi.directions(dir, chdirs, widstart, chs,
- widstart, end - start);
+ mLineDirections[j] = AndroidBidi.directions(dir, chdirs, widthStart, chs,
+ widthStart, end - start);
}
// If ellipsize is in marquee mode, do not apply ellipsis on the first line
if (ellipsize != null && (ellipsize != TextUtils.TruncateAt.MARQUEE || j != 0)) {
- calculateEllipsis(start, end, widths, widstart,
- ellipsiswidth, ellipsize, j,
- textwidth, paint);
+ calculateEllipsis(start, end, widths, widthStart,
+ ellipsisWidth, ellipsize, j,
+ textWidth, paint);
}
mLineCount++;
return v;
}
- private void calculateEllipsis(int linestart, int lineend,
- float[] widths, int widstart,
+ private void calculateEllipsis(int lineStart, int lineEnd,
+ float[] widths, int widthStart,
float avail, TextUtils.TruncateAt where,
- int line, float textwidth, TextPaint paint) {
+ int line, float textWidth, TextPaint paint) {
- if (textwidth <= avail) {
+ if (textWidth <= avail) {
// Everything fits!
mLines[mColumns * line + ELLIPSIS_START] = 0;
mLines[mColumns * line + ELLIPSIS_COUNT] = 0;
return;
}
- float ellipsiswid = paint.measureText("\u2026");
+ float ellipsisWidth = paint.measureText(HORIZONTAL_ELLIPSIS);
int ellipsisStart, ellipsisCount;
- int len = lineend - linestart;
+ int len = lineEnd - lineStart;
if (where == TextUtils.TruncateAt.START) {
float sum = 0;
int i;
for (i = len; i >= 0; i--) {
- float w = widths[i - 1 + linestart - widstart];
+ float w = widths[i - 1 + lineStart - widthStart];
- if (w + sum + ellipsiswid > avail) {
+ if (w + sum + ellipsisWidth > avail) {
break;
}
@@ -787,9 +781,9 @@
int i;
for (i = 0; i < len; i++) {
- float w = widths[i + linestart - widstart];
+ float w = widths[i + lineStart - widthStart];
- if (w + sum + ellipsiswid > avail) {
+ if (w + sum + ellipsisWidth > avail) {
break;
}
@@ -802,9 +796,9 @@
float lsum = 0, rsum = 0;
int left = 0, right = len;
- float ravail = (avail - ellipsiswid) / 2;
+ float ravail = (avail - ellipsisWidth) / 2;
for (right = len; right >= 0; right--) {
- float w = widths[right - 1 + linestart - widstart];
+ float w = widths[right - 1 + lineStart - widthStart];
if (w + rsum > ravail) {
break;
@@ -813,9 +807,9 @@
rsum += w;
}
- float lavail = avail - ellipsiswid - rsum;
+ float lavail = avail - ellipsisWidth - rsum;
for (left = 0; left < right; left++) {
- float w = widths[left + linestart - widstart];
+ float w = widths[left + lineStart - widthStart];
if (w + lsum > lavail) {
break;
@@ -968,6 +962,24 @@
private static final int TAB_INCREMENT = 20; // same as Layout, but that's private
+ private static final char CHAR_FIRST_CJK = '\u2E80';
+
+ private static final char CHAR_NEW_LINE = '\n';
+ private static final char CHAR_TAB = '\t';
+ private static final char CHAR_SPACE = ' ';
+ private static final char CHAR_DOT = '.';
+ private static final char CHAR_COMMA = ',';
+ private static final char CHAR_COLON = ':';
+ private static final char CHAR_SEMICOLON = ';';
+ private static final char CHAR_SLASH = '/';
+ private static final char CHAR_HYPHEN = '-';
+
+ private static final double EXTRA_ROUNDING = 0.5;
+ private static final String HORIZONTAL_ELLIPSIS = "\u2026"; // this is "..."
+
+ private static final int CHAR_FIRST_HIGH_SURROGATE = 0xD800;
+ private static final int CHAR_LAST_LOW_SURROGATE = 0xDFFF;
+
/*
* This is reused across calls to generate()
*/
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index e799f76..def1161 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -20,6 +20,7 @@
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.SparseArray;
/**
* Describes the capabilities of a particular input device.
@@ -41,9 +42,10 @@
private String mName;
private int mSources;
private int mKeyboardType;
-
- private MotionRange[] mMotionRanges;
-
+
+ private final SparseArray<MotionRange> mMotionRanges = new SparseArray<MotionRange>();
+ private int[] mMotionAxes;
+
/**
* A mask for input source classes.
*
@@ -181,70 +183,85 @@
public static final int SOURCE_ANY = 0xffffff00;
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#x}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_X} instead.
*/
- public static final int MOTION_RANGE_X = 0;
-
+ @Deprecated
+ public static final int MOTION_RANGE_X = MotionEvent.AXIS_X;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#y}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_Y} instead.
*/
- public static final int MOTION_RANGE_Y = 1;
-
+ @Deprecated
+ public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#pressure}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead.
*/
- public static final int MOTION_RANGE_PRESSURE = 2;
-
+ @Deprecated
+ public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#size}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead.
*/
- public static final int MOTION_RANGE_SIZE = 3;
-
+ @Deprecated
+ public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#touchMajor}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead.
*/
- public static final int MOTION_RANGE_TOUCH_MAJOR = 4;
-
+ @Deprecated
+ public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#touchMinor}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead.
*/
- public static final int MOTION_RANGE_TOUCH_MINOR = 5;
-
+ @Deprecated
+ public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#toolMajor}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead.
*/
- public static final int MOTION_RANGE_TOOL_MAJOR = 6;
-
+ @Deprecated
+ public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR;
+
/**
- * Constant for retrieving the range of values for {@link MotionEvent.PointerCoords#toolMinor}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead.
*/
- public static final int MOTION_RANGE_TOOL_MINOR = 7;
-
+ @Deprecated
+ public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR;
+
/**
- * Constant for retrieving the range of values for
- * {@link MotionEvent.PointerCoords#orientation}.
+ * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}.
*
* @see #getMotionRange
+ * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead.
*/
- public static final int MOTION_RANGE_ORIENTATION = 8;
-
- private static final int MOTION_RANGE_LAST = MOTION_RANGE_ORIENTATION;
+ @Deprecated
+ public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION;
/**
* There is no keyboard.
@@ -261,10 +278,9 @@
* The keyboard supports a complement of alphabetic keys.
*/
public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
-
+
// Called by native code.
private InputDevice() {
- mMotionRanges = new MotionRange[MOTION_RANGE_LAST + 1];
}
/**
@@ -335,91 +351,111 @@
public KeyCharacterMap getKeyCharacterMap() {
return KeyCharacterMap.load(mId);
}
-
+
/**
- * Gets information about the range of values for a particular {@link MotionEvent}
- * coordinate.
- * @param rangeType The motion range constant.
- * @return The range of values, or null if the requested coordinate is not
+ * Gets information about the range of values for a particular {@link MotionEvent} axis.
+ * @param axis The axis constant.
+ * @return The range of values, or null if the requested axis is not
* supported by the device.
+ *
+ * @see MotionEvent#AXIS_X
+ * @see MotionEvent#AXIS_Y
+ * @see #getSupportedAxes()
*/
- public MotionRange getMotionRange(int rangeType) {
- if (rangeType < 0 || rangeType > MOTION_RANGE_LAST) {
- throw new IllegalArgumentException("Requested range is out of bounds.");
- }
-
- return mMotionRanges[rangeType];
+ public MotionRange getMotionRange(int axis) {
+ return mMotionRanges.get(axis);
}
-
- private void addMotionRange(int rangeType, float min, float max, float flat, float fuzz) {
- if (rangeType >= 0 && rangeType <= MOTION_RANGE_LAST) {
- MotionRange range = new MotionRange(min, max, flat, fuzz);
- mMotionRanges[rangeType] = range;
- }
- }
-
+
/**
- * Provides information about the range of values for a particular {@link MotionEvent}
- * coordinate.
+ * Gets the axis ids of all motion axes supported by this device.
+ * @return The axis ids of all motion axes supported by this device.
+ *
+ * @see #getMotionRange(int)
+ */
+ public int[] getMotionAxes() {
+ synchronized (this) {
+ if (mMotionAxes == null) {
+ final int count = mMotionRanges.size();
+ mMotionAxes = new int[count];
+ for (int i = 0; i < count; i++) {
+ mMotionAxes[i] = mMotionRanges.keyAt(i);
+ }
+ }
+ return mMotionAxes;
+ }
+ }
+
+ private void addMotionRange(int axis, float min, float max, float flat, float fuzz) {
+ mMotionRanges.append(axis, new MotionRange(min, max, flat, fuzz));
+ }
+
+ /**
+ * Provides information about the range of values for a particular {@link MotionEvent} axis.
+ *
+ * @see InputDevice#getMotionRange(int)
*/
public static final class MotionRange {
private float mMin;
private float mMax;
private float mFlat;
private float mFuzz;
-
+
private MotionRange(float min, float max, float flat, float fuzz) {
mMin = min;
mMax = max;
mFlat = flat;
mFuzz = fuzz;
}
-
+
/**
- * Gets the minimum value for the coordinate.
- * @return The minimum value.
+ * Gets the inclusive minimum value for the axis.
+ * @return The inclusive minimum value.
*/
public float getMin() {
return mMin;
}
-
+
/**
- * Gets the maximum value for the coordinate.
- * @return The minimum value.
+ * Gets the inclusive maximum value for the axis.
+ * @return The inclusive maximum value.
*/
public float getMax() {
return mMax;
}
-
+
/**
- * Gets the range of the coordinate (difference between maximum and minimum).
+ * Gets the range of the axis (difference between maximum and minimum).
* @return The range of values.
*/
public float getRange() {
return mMax - mMin;
}
-
+
/**
- * Gets the extent of the center flat position with respect to this coordinate.
+ * Gets the extent of the center flat position with respect to this axis.
+ * <p>
* For example, a flat value of 8 means that the center position is between -8 and +8.
* This value is mainly useful for calibrating self-centering devices.
+ * </p>
* @return The extent of the center flat position.
*/
public float getFlat() {
return mFlat;
}
-
+
/**
- * Gets the error tolerance for input device measurements with respect to this coordinate.
+ * Gets the error tolerance for input device measurements with respect to this axis.
+ * <p>
* For example, a value of 2 indicates that the measured value may be up to +/- 2 units
* away from the actual value due to noise and device sensitivity limitations.
+ * </p>
* @return The error tolerance.
*/
public float getFuzz() {
return mFuzz;
}
}
-
+
public static final Parcelable.Creator<InputDevice> CREATOR
= new Parcelable.Creator<InputDevice>() {
public InputDevice createFromParcel(Parcel in) {
@@ -438,15 +474,13 @@
mName = in.readString();
mSources = in.readInt();
mKeyboardType = in.readInt();
-
+
for (;;) {
- int rangeType = in.readInt();
- if (rangeType < 0) {
+ int axis = in.readInt();
+ if (axis < 0) {
break;
}
-
- addMotionRange(rangeType,
- in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
+ addMotionRange(axis, in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
}
}
@@ -456,25 +490,25 @@
out.writeString(mName);
out.writeInt(mSources);
out.writeInt(mKeyboardType);
-
- for (int i = 0; i <= MOTION_RANGE_LAST; i++) {
- MotionRange range = mMotionRanges[i];
- if (range != null) {
- out.writeInt(i);
- out.writeFloat(range.mMin);
- out.writeFloat(range.mMax);
- out.writeFloat(range.mFlat);
- out.writeFloat(range.mFuzz);
- }
+
+ final int numAxes = mMotionRanges.size();
+ for (int i = 0; i < numAxes; i++) {
+ int axis = mMotionRanges.keyAt(i);
+ MotionRange range = mMotionRanges.valueAt(i);
+ out.writeInt(axis);
+ out.writeFloat(range.mMin);
+ out.writeFloat(range.mMax);
+ out.writeFloat(range.mFlat);
+ out.writeFloat(range.mFuzz);
}
out.writeInt(-1);
}
-
+
@Override
public int describeContents() {
return 0;
}
-
+
@Override
public String toString() {
StringBuilder description = new StringBuilder();
@@ -493,29 +527,32 @@
break;
}
description.append("\n");
-
- description.append(" Sources:");
+
+ description.append(" Sources: ").append(Integer.toHexString(mSources)).append(" (");
appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
- description.append("\n");
-
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_X, "x");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_Y, "y");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_PRESSURE, "pressure");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_SIZE, "size");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MAJOR, "touchMajor");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOUCH_MINOR, "touchMinor");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MAJOR, "toolMajor");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_TOOL_MINOR, "toolMinor");
- appendRangeDescriptionIfApplicable(description, MOTION_RANGE_ORIENTATION, "orientation");
-
+ appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick");
+ appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
+ description.append(" )\n");
+
+ final int numAxes = mMotionRanges.size();
+ for (int i = 0; i < numAxes; i++) {
+ int axis = mMotionRanges.keyAt(i);
+ MotionRange range = mMotionRanges.valueAt(i);
+ description.append(" ").append(MotionEvent.axisToString(axis));
+ description.append(": min=").append(range.mMin);
+ description.append(" max=").append(range.mMax);
+ description.append(" flat=").append(range.mFlat);
+ description.append(" fuzz=").append(range.mFuzz);
+ description.append("\n");
+ }
return description.toString();
}
-
+
private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
String sourceName) {
if ((mSources & source) == source) {
@@ -523,17 +560,4 @@
description.append(sourceName);
}
}
-
- private void appendRangeDescriptionIfApplicable(StringBuilder description,
- int rangeType, String rangeName) {
- MotionRange range = mMotionRanges[rangeType];
- if (range != null) {
- description.append(" Range[").append(rangeName);
- description.append("]: min=").append(range.mMin);
- description.append(" max=").append(range.mMax);
- description.append(" flat=").append(range.mFlat);
- description.append(" fuzz=").append(range.mFuzz);
- description.append("\n");
- }
- }
}
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 184e0fc..f6aeb39 100755
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -24,11 +24,6 @@
*/
public abstract class InputEvent implements Parcelable {
/** @hide */
- protected int mDeviceId;
- /** @hide */
- protected int mSource;
-
- /** @hide */
protected static final int PARCEL_TOKEN_MOTION_EVENT = 1;
/** @hide */
protected static final int PARCEL_TOKEN_KEY_EVENT = 2;
@@ -45,55 +40,37 @@
* @return The device id.
* @see InputDevice#getDevice
*/
- public final int getDeviceId() {
- return mDeviceId;
- }
-
+ public abstract int getDeviceId();
+
/**
* Gets the device that this event came from.
*
* @return The device, or null if unknown.
*/
public final InputDevice getDevice() {
- return InputDevice.getDevice(mDeviceId);
+ return InputDevice.getDevice(getDeviceId());
}
-
+
/**
* Gets the source of the event.
*
* @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown.
* @see InputDevice#getSourceInfo
*/
- public final int getSource() {
- return mSource;
- }
-
+ public abstract int getSource();
+
/**
* Modifies the source of the event.
- * @param source The source.
- *
+ *
+ * @param source The new source.
* @hide
*/
- public final void setSource(int source) {
- mSource = source;
- }
-
+ public abstract void setSource(int source);
+
public int describeContents() {
return 0;
}
-
- /** @hide */
- protected final void readBaseFromParcel(Parcel in) {
- mDeviceId = in.readInt();
- mSource = in.readInt();
- }
-
- /** @hide */
- protected final void writeBaseToParcel(Parcel out) {
- out.writeInt(mDeviceId);
- out.writeInt(mSource);
- }
-
+
public static final Parcelable.Creator<InputEvent> CREATOR
= new Parcelable.Creator<InputEvent>() {
public InputEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 766969a..81d5a6e 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -21,6 +21,7 @@
import android.text.method.MetaKeyKeyListener;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap.KeyData;
@@ -582,213 +583,214 @@
// those new codes. This is intended to maintain a consistent
// set of key code definitions across all Android devices.
- // Symbolic names of all keys indexed by keycode.
- // There should be exactly LAST_KEYCODE + 1 entries in this table.
- private static final String[] KEYCODE_SYMBOLIC_NAMES = new String[] {
- "KEYCODE_UNKNOWN",
- "KEYCODE_SOFT_LEFT",
- "KEYCODE_SOFT_RIGHT",
- "KEYCODE_HOME",
- "KEYCODE_BACK",
- "KEYCODE_CALL",
- "KEYCODE_ENDCALL",
- "KEYCODE_0",
- "KEYCODE_1",
- "KEYCODE_2",
- "KEYCODE_3",
- "KEYCODE_4",
- "KEYCODE_5",
- "KEYCODE_6",
- "KEYCODE_7",
- "KEYCODE_8",
- "KEYCODE_9",
- "KEYCODE_STAR",
- "KEYCODE_POUND",
- "KEYCODE_DPAD_UP",
- "KEYCODE_DPAD_DOWN",
- "KEYCODE_DPAD_LEFT",
- "KEYCODE_DPAD_RIGHT",
- "KEYCODE_DPAD_CENTER",
- "KEYCODE_VOLUME_UP",
- "KEYCODE_VOLUME_DOWN",
- "KEYCODE_POWER",
- "KEYCODE_CAMERA",
- "KEYCODE_CLEAR",
- "KEYCODE_A",
- "KEYCODE_B",
- "KEYCODE_C",
- "KEYCODE_D",
- "KEYCODE_E",
- "KEYCODE_F",
- "KEYCODE_G",
- "KEYCODE_H",
- "KEYCODE_I",
- "KEYCODE_J",
- "KEYCODE_K",
- "KEYCODE_L",
- "KEYCODE_M",
- "KEYCODE_N",
- "KEYCODE_O",
- "KEYCODE_P",
- "KEYCODE_Q",
- "KEYCODE_R",
- "KEYCODE_S",
- "KEYCODE_T",
- "KEYCODE_U",
- "KEYCODE_V",
- "KEYCODE_W",
- "KEYCODE_X",
- "KEYCODE_Y",
- "KEYCODE_Z",
- "KEYCODE_COMMA",
- "KEYCODE_PERIOD",
- "KEYCODE_ALT_LEFT",
- "KEYCODE_ALT_RIGHT",
- "KEYCODE_SHIFT_LEFT",
- "KEYCODE_SHIFT_RIGHT",
- "KEYCODE_TAB",
- "KEYCODE_SPACE",
- "KEYCODE_SYM",
- "KEYCODE_EXPLORER",
- "KEYCODE_ENVELOPE",
- "KEYCODE_ENTER",
- "KEYCODE_DEL",
- "KEYCODE_GRAVE",
- "KEYCODE_MINUS",
- "KEYCODE_EQUALS",
- "KEYCODE_LEFT_BRACKET",
- "KEYCODE_RIGHT_BRACKET",
- "KEYCODE_BACKSLASH",
- "KEYCODE_SEMICOLON",
- "KEYCODE_APOSTROPHE",
- "KEYCODE_SLASH",
- "KEYCODE_AT",
- "KEYCODE_NUM",
- "KEYCODE_HEADSETHOOK",
- "KEYCODE_FOCUS",
- "KEYCODE_PLUS",
- "KEYCODE_MENU",
- "KEYCODE_NOTIFICATION",
- "KEYCODE_SEARCH",
- "KEYCODE_MEDIA_PLAY_PAUSE",
- "KEYCODE_MEDIA_STOP",
- "KEYCODE_MEDIA_NEXT",
- "KEYCODE_MEDIA_PREVIOUS",
- "KEYCODE_MEDIA_REWIND",
- "KEYCODE_MEDIA_FAST_FORWARD",
- "KEYCODE_MUTE",
- "KEYCODE_PAGE_UP",
- "KEYCODE_PAGE_DOWN",
- "KEYCODE_PICTSYMBOLS",
- "KEYCODE_SWITCH_CHARSET",
- "KEYCODE_BUTTON_A",
- "KEYCODE_BUTTON_B",
- "KEYCODE_BUTTON_C",
- "KEYCODE_BUTTON_X",
- "KEYCODE_BUTTON_Y",
- "KEYCODE_BUTTON_Z",
- "KEYCODE_BUTTON_L1",
- "KEYCODE_BUTTON_R1",
- "KEYCODE_BUTTON_L2",
- "KEYCODE_BUTTON_R2",
- "KEYCODE_BUTTON_THUMBL",
- "KEYCODE_BUTTON_THUMBR",
- "KEYCODE_BUTTON_START",
- "KEYCODE_BUTTON_SELECT",
- "KEYCODE_BUTTON_MODE",
- "KEYCODE_ESCAPE",
- "KEYCODE_FORWARD_DEL",
- "KEYCODE_CTRL_LEFT",
- "KEYCODE_CTRL_RIGHT",
- "KEYCODE_CAPS_LOCK",
- "KEYCODE_SCROLL_LOCK",
- "KEYCODE_META_LEFT",
- "KEYCODE_META_RIGHT",
- "KEYCODE_FUNCTION",
- "KEYCODE_SYSRQ",
- "KEYCODE_BREAK",
- "KEYCODE_MOVE_HOME",
- "KEYCODE_MOVE_END",
- "KEYCODE_INSERT",
- "KEYCODE_FORWARD",
- "KEYCODE_MEDIA_PLAY",
- "KEYCODE_MEDIA_PAUSE",
- "KEYCODE_MEDIA_CLOSE",
- "KEYCODE_MEDIA_EJECT",
- "KEYCODE_MEDIA_RECORD",
- "KEYCODE_F1",
- "KEYCODE_F2",
- "KEYCODE_F3",
- "KEYCODE_F4",
- "KEYCODE_F5",
- "KEYCODE_F6",
- "KEYCODE_F7",
- "KEYCODE_F8",
- "KEYCODE_F9",
- "KEYCODE_F10",
- "KEYCODE_F11",
- "KEYCODE_F12",
- "KEYCODE_NUM_LOCK",
- "KEYCODE_NUMPAD_0",
- "KEYCODE_NUMPAD_1",
- "KEYCODE_NUMPAD_2",
- "KEYCODE_NUMPAD_3",
- "KEYCODE_NUMPAD_4",
- "KEYCODE_NUMPAD_5",
- "KEYCODE_NUMPAD_6",
- "KEYCODE_NUMPAD_7",
- "KEYCODE_NUMPAD_8",
- "KEYCODE_NUMPAD_9",
- "KEYCODE_NUMPAD_DIVIDE",
- "KEYCODE_NUMPAD_MULTIPLY",
- "KEYCODE_MUMPAD_SUBTRACT",
- "KEYCODE_NUMPAD_ADD",
- "KEYCODE_NUMPAD_DOT",
- "KEYCODE_NUMPAD_COMMA",
- "KEYCODE_NUMPAD_ENTER",
- "KEYCODE_NUMPAD_EQUALS",
- "KEYCODE_NUMPAD_LEFT_PAREN",
- "KEYCODE_NUMPAD_RIGHT_PAREN",
- "KEYCODE_VOLUME_MUTE",
- "KEYCODE_INFO",
- "KEYCODE_CHANNEL_UP",
- "KEYCODE_CHANNEL_DOWN",
- "KEYCODE_ZOOM_IN",
- "KEYCODE_ZOOM_OUT",
- "KEYCODE_TV",
- "KEYCODE_WINDOW",
- "KEYCODE_GUIDE",
- "KEYCODE_DVR",
- "KEYCODE_BOOKMARK",
- "KEYCODE_CAPTIONS",
- "KEYCODE_SETTINGS",
- "KEYCODE_TV_POWER",
- "KEYCODE_TV_INPUT",
- "KEYCODE_STB_INPUT",
- "KEYCODE_STB_POWER",
- "KEYCODE_AVR_POWER",
- "KEYCODE_AVR_INPUT",
- "KEYCODE_PROG_RED",
- "KEYCODE_PROG_GREEN",
- "KEYCODE_PROG_YELLOW",
- "KEYCODE_PROG_BLUE",
- "KEYCODE_APP_SWITCH",
- "KEYCODE_BUTTON_1",
- "KEYCODE_BUTTON_2",
- "KEYCODE_BUTTON_3",
- "KEYCODE_BUTTON_4",
- "KEYCODE_BUTTON_5",
- "KEYCODE_BUTTON_6",
- "KEYCODE_BUTTON_7",
- "KEYCODE_BUTTON_8",
- "KEYCODE_BUTTON_9",
- "KEYCODE_BUTTON_10",
- "KEYCODE_BUTTON_11",
- "KEYCODE_BUTTON_12",
- "KEYCODE_BUTTON_13",
- "KEYCODE_BUTTON_14",
- "KEYCODE_BUTTON_15",
- "KEYCODE_BUTTON_16",
+ // Symbolic names of all key codes.
+ private static final SparseArray<String> KEYCODE_SYMBOLIC_NAMES = new SparseArray<String>();
+ private static void populateKeycodeSymbolicNames() {
+ SparseArray<String> names = KEYCODE_SYMBOLIC_NAMES;
+ names.append(KEYCODE_UNKNOWN, "KEYCODE_UNKNOWN");
+ names.append(KEYCODE_SOFT_LEFT, "KEYCODE_SOFT_LEFT");
+ names.append(KEYCODE_SOFT_RIGHT, "KEYCODE_SOFT_RIGHT");
+ names.append(KEYCODE_HOME, "KEYCODE_HOME");
+ names.append(KEYCODE_BACK, "KEYCODE_BACK");
+ names.append(KEYCODE_CALL, "KEYCODE_CALL");
+ names.append(KEYCODE_ENDCALL, "KEYCODE_ENDCALL");
+ names.append(KEYCODE_0, "KEYCODE_0");
+ names.append(KEYCODE_1, "KEYCODE_1");
+ names.append(KEYCODE_2, "KEYCODE_2");
+ names.append(KEYCODE_3, "KEYCODE_3");
+ names.append(KEYCODE_4, "KEYCODE_4");
+ names.append(KEYCODE_5, "KEYCODE_5");
+ names.append(KEYCODE_6, "KEYCODE_6");
+ names.append(KEYCODE_7, "KEYCODE_7");
+ names.append(KEYCODE_8, "KEYCODE_8");
+ names.append(KEYCODE_9, "KEYCODE_9");
+ names.append(KEYCODE_STAR, "KEYCODE_STAR");
+ names.append(KEYCODE_POUND, "KEYCODE_POUND");
+ names.append(KEYCODE_DPAD_UP, "KEYCODE_DPAD_UP");
+ names.append(KEYCODE_DPAD_DOWN, "KEYCODE_DPAD_DOWN");
+ names.append(KEYCODE_DPAD_LEFT, "KEYCODE_DPAD_LEFT");
+ names.append(KEYCODE_DPAD_RIGHT, "KEYCODE_DPAD_RIGHT");
+ names.append(KEYCODE_DPAD_CENTER, "KEYCODE_DPAD_CENTER");
+ names.append(KEYCODE_VOLUME_UP, "KEYCODE_VOLUME_UP");
+ names.append(KEYCODE_VOLUME_DOWN, "KEYCODE_VOLUME_DOWN");
+ names.append(KEYCODE_POWER, "KEYCODE_POWER");
+ names.append(KEYCODE_CAMERA, "KEYCODE_CAMERA");
+ names.append(KEYCODE_CLEAR, "KEYCODE_CLEAR");
+ names.append(KEYCODE_A, "KEYCODE_A");
+ names.append(KEYCODE_B, "KEYCODE_B");
+ names.append(KEYCODE_C, "KEYCODE_C");
+ names.append(KEYCODE_D, "KEYCODE_D");
+ names.append(KEYCODE_E, "KEYCODE_E");
+ names.append(KEYCODE_F, "KEYCODE_F");
+ names.append(KEYCODE_G, "KEYCODE_G");
+ names.append(KEYCODE_H, "KEYCODE_H");
+ names.append(KEYCODE_I, "KEYCODE_I");
+ names.append(KEYCODE_J, "KEYCODE_J");
+ names.append(KEYCODE_K, "KEYCODE_K");
+ names.append(KEYCODE_L, "KEYCODE_L");
+ names.append(KEYCODE_M, "KEYCODE_M");
+ names.append(KEYCODE_N, "KEYCODE_N");
+ names.append(KEYCODE_O, "KEYCODE_O");
+ names.append(KEYCODE_P, "KEYCODE_P");
+ names.append(KEYCODE_Q, "KEYCODE_Q");
+ names.append(KEYCODE_R, "KEYCODE_R");
+ names.append(KEYCODE_S, "KEYCODE_S");
+ names.append(KEYCODE_T, "KEYCODE_T");
+ names.append(KEYCODE_U, "KEYCODE_U");
+ names.append(KEYCODE_V, "KEYCODE_V");
+ names.append(KEYCODE_W, "KEYCODE_W");
+ names.append(KEYCODE_X, "KEYCODE_X");
+ names.append(KEYCODE_Y, "KEYCODE_Y");
+ names.append(KEYCODE_Z, "KEYCODE_Z");
+ names.append(KEYCODE_COMMA, "KEYCODE_COMMA");
+ names.append(KEYCODE_PERIOD, "KEYCODE_PERIOD");
+ names.append(KEYCODE_ALT_LEFT, "KEYCODE_ALT_LEFT");
+ names.append(KEYCODE_ALT_RIGHT, "KEYCODE_ALT_RIGHT");
+ names.append(KEYCODE_SHIFT_LEFT, "KEYCODE_SHIFT_LEFT");
+ names.append(KEYCODE_SHIFT_RIGHT, "KEYCODE_SHIFT_RIGHT");
+ names.append(KEYCODE_TAB, "KEYCODE_TAB");
+ names.append(KEYCODE_SPACE, "KEYCODE_SPACE");
+ names.append(KEYCODE_SYM, "KEYCODE_SYM");
+ names.append(KEYCODE_EXPLORER, "KEYCODE_EXPLORER");
+ names.append(KEYCODE_ENVELOPE, "KEYCODE_ENVELOPE");
+ names.append(KEYCODE_ENTER, "KEYCODE_ENTER");
+ names.append(KEYCODE_DEL, "KEYCODE_DEL");
+ names.append(KEYCODE_GRAVE, "KEYCODE_GRAVE");
+ names.append(KEYCODE_MINUS, "KEYCODE_MINUS");
+ names.append(KEYCODE_EQUALS, "KEYCODE_EQUALS");
+ names.append(KEYCODE_LEFT_BRACKET, "KEYCODE_LEFT_BRACKET");
+ names.append(KEYCODE_RIGHT_BRACKET, "KEYCODE_RIGHT_BRACKET");
+ names.append(KEYCODE_BACKSLASH, "KEYCODE_BACKSLASH");
+ names.append(KEYCODE_SEMICOLON, "KEYCODE_SEMICOLON");
+ names.append(KEYCODE_APOSTROPHE, "KEYCODE_APOSTROPHE");
+ names.append(KEYCODE_SLASH, "KEYCODE_SLASH");
+ names.append(KEYCODE_AT, "KEYCODE_AT");
+ names.append(KEYCODE_NUM, "KEYCODE_NUM");
+ names.append(KEYCODE_HEADSETHOOK, "KEYCODE_HEADSETHOOK");
+ names.append(KEYCODE_FOCUS, "KEYCODE_FOCUS");
+ names.append(KEYCODE_PLUS, "KEYCODE_PLUS");
+ names.append(KEYCODE_MENU, "KEYCODE_MENU");
+ names.append(KEYCODE_NOTIFICATION, "KEYCODE_NOTIFICATION");
+ names.append(KEYCODE_SEARCH, "KEYCODE_SEARCH");
+ names.append(KEYCODE_MEDIA_PLAY_PAUSE, "KEYCODE_MEDIA_PLAY_PAUSE");
+ names.append(KEYCODE_MEDIA_STOP, "KEYCODE_MEDIA_STOP");
+ names.append(KEYCODE_MEDIA_NEXT, "KEYCODE_MEDIA_NEXT");
+ names.append(KEYCODE_MEDIA_PREVIOUS, "KEYCODE_MEDIA_PREVIOUS");
+ names.append(KEYCODE_MEDIA_REWIND, "KEYCODE_MEDIA_REWIND");
+ names.append(KEYCODE_MEDIA_FAST_FORWARD, "KEYCODE_MEDIA_FAST_FORWARD");
+ names.append(KEYCODE_MUTE, "KEYCODE_MUTE");
+ names.append(KEYCODE_PAGE_UP, "KEYCODE_PAGE_UP");
+ names.append(KEYCODE_PAGE_DOWN, "KEYCODE_PAGE_DOWN");
+ names.append(KEYCODE_PICTSYMBOLS, "KEYCODE_PICTSYMBOLS");
+ names.append(KEYCODE_SWITCH_CHARSET, "KEYCODE_SWITCH_CHARSET");
+ names.append(KEYCODE_BUTTON_A, "KEYCODE_BUTTON_A");
+ names.append(KEYCODE_BUTTON_B, "KEYCODE_BUTTON_B");
+ names.append(KEYCODE_BUTTON_C, "KEYCODE_BUTTON_C");
+ names.append(KEYCODE_BUTTON_X, "KEYCODE_BUTTON_X");
+ names.append(KEYCODE_BUTTON_Y, "KEYCODE_BUTTON_Y");
+ names.append(KEYCODE_BUTTON_Z, "KEYCODE_BUTTON_Z");
+ names.append(KEYCODE_BUTTON_L1, "KEYCODE_BUTTON_L1");
+ names.append(KEYCODE_BUTTON_R1, "KEYCODE_BUTTON_R1");
+ names.append(KEYCODE_BUTTON_L2, "KEYCODE_BUTTON_L2");
+ names.append(KEYCODE_BUTTON_R2, "KEYCODE_BUTTON_R2");
+ names.append(KEYCODE_BUTTON_THUMBL, "KEYCODE_BUTTON_THUMBL");
+ names.append(KEYCODE_BUTTON_THUMBR, "KEYCODE_BUTTON_THUMBR");
+ names.append(KEYCODE_BUTTON_START, "KEYCODE_BUTTON_START");
+ names.append(KEYCODE_BUTTON_SELECT, "KEYCODE_BUTTON_SELECT");
+ names.append(KEYCODE_BUTTON_MODE, "KEYCODE_BUTTON_MODE");
+ names.append(KEYCODE_ESCAPE, "KEYCODE_ESCAPE");
+ names.append(KEYCODE_FORWARD_DEL, "KEYCODE_FORWARD_DEL");
+ names.append(KEYCODE_CTRL_LEFT, "KEYCODE_CTRL_LEFT");
+ names.append(KEYCODE_CTRL_RIGHT, "KEYCODE_CTRL_RIGHT");
+ names.append(KEYCODE_CAPS_LOCK, "KEYCODE_CAPS_LOCK");
+ names.append(KEYCODE_SCROLL_LOCK, "KEYCODE_SCROLL_LOCK");
+ names.append(KEYCODE_META_LEFT, "KEYCODE_META_LEFT");
+ names.append(KEYCODE_META_RIGHT, "KEYCODE_META_RIGHT");
+ names.append(KEYCODE_FUNCTION, "KEYCODE_FUNCTION");
+ names.append(KEYCODE_SYSRQ, "KEYCODE_SYSRQ");
+ names.append(KEYCODE_BREAK, "KEYCODE_BREAK");
+ names.append(KEYCODE_MOVE_HOME, "KEYCODE_MOVE_HOME");
+ names.append(KEYCODE_MOVE_END, "KEYCODE_MOVE_END");
+ names.append(KEYCODE_INSERT, "KEYCODE_INSERT");
+ names.append(KEYCODE_FORWARD, "KEYCODE_FORWARD");
+ names.append(KEYCODE_MEDIA_PLAY, "KEYCODE_MEDIA_PLAY");
+ names.append(KEYCODE_MEDIA_PAUSE, "KEYCODE_MEDIA_PAUSE");
+ names.append(KEYCODE_MEDIA_CLOSE, "KEYCODE_MEDIA_CLOSE");
+ names.append(KEYCODE_MEDIA_EJECT, "KEYCODE_MEDIA_EJECT");
+ names.append(KEYCODE_MEDIA_RECORD, "KEYCODE_MEDIA_RECORD");
+ names.append(KEYCODE_F1, "KEYCODE_F1");
+ names.append(KEYCODE_F2, "KEYCODE_F2");
+ names.append(KEYCODE_F3, "KEYCODE_F3");
+ names.append(KEYCODE_F4, "KEYCODE_F4");
+ names.append(KEYCODE_F5, "KEYCODE_F5");
+ names.append(KEYCODE_F6, "KEYCODE_F6");
+ names.append(KEYCODE_F7, "KEYCODE_F7");
+ names.append(KEYCODE_F8, "KEYCODE_F8");
+ names.append(KEYCODE_F9, "KEYCODE_F9");
+ names.append(KEYCODE_F10, "KEYCODE_F10");
+ names.append(KEYCODE_F11, "KEYCODE_F11");
+ names.append(KEYCODE_F12, "KEYCODE_F12");
+ names.append(KEYCODE_NUM_LOCK, "KEYCODE_NUM_LOCK");
+ names.append(KEYCODE_NUMPAD_0, "KEYCODE_NUMPAD_0");
+ names.append(KEYCODE_NUMPAD_1, "KEYCODE_NUMPAD_1");
+ names.append(KEYCODE_NUMPAD_2, "KEYCODE_NUMPAD_2");
+ names.append(KEYCODE_NUMPAD_3, "KEYCODE_NUMPAD_3");
+ names.append(KEYCODE_NUMPAD_4, "KEYCODE_NUMPAD_4");
+ names.append(KEYCODE_NUMPAD_5, "KEYCODE_NUMPAD_5");
+ names.append(KEYCODE_NUMPAD_6, "KEYCODE_NUMPAD_6");
+ names.append(KEYCODE_NUMPAD_7, "KEYCODE_NUMPAD_7");
+ names.append(KEYCODE_NUMPAD_8, "KEYCODE_NUMPAD_8");
+ names.append(KEYCODE_NUMPAD_9, "KEYCODE_NUMPAD_9");
+ names.append(KEYCODE_NUMPAD_DIVIDE, "KEYCODE_NUMPAD_DIVIDE");
+ names.append(KEYCODE_NUMPAD_MULTIPLY, "KEYCODE_NUMPAD_MULTIPLY");
+ names.append(KEYCODE_NUMPAD_SUBTRACT, "KEYCODE_NUMPAD_SUBTRACT");
+ names.append(KEYCODE_NUMPAD_ADD, "KEYCODE_NUMPAD_ADD");
+ names.append(KEYCODE_NUMPAD_DOT, "KEYCODE_NUMPAD_DOT");
+ names.append(KEYCODE_NUMPAD_COMMA, "KEYCODE_NUMPAD_COMMA");
+ names.append(KEYCODE_NUMPAD_ENTER, "KEYCODE_NUMPAD_ENTER");
+ names.append(KEYCODE_NUMPAD_EQUALS, "KEYCODE_NUMPAD_EQUALS");
+ names.append(KEYCODE_NUMPAD_LEFT_PAREN, "KEYCODE_NUMPAD_LEFT_PAREN");
+ names.append(KEYCODE_NUMPAD_RIGHT_PAREN, "KEYCODE_NUMPAD_RIGHT_PAREN");
+ names.append(KEYCODE_VOLUME_MUTE, "KEYCODE_VOLUME_MUTE");
+ names.append(KEYCODE_INFO, "KEYCODE_INFO");
+ names.append(KEYCODE_CHANNEL_UP, "KEYCODE_CHANNEL_UP");
+ names.append(KEYCODE_CHANNEL_DOWN, "KEYCODE_CHANNEL_DOWN");
+ names.append(KEYCODE_ZOOM_IN, "KEYCODE_ZOOM_IN");
+ names.append(KEYCODE_ZOOM_OUT, "KEYCODE_ZOOM_OUT");
+ names.append(KEYCODE_TV, "KEYCODE_TV");
+ names.append(KEYCODE_WINDOW, "KEYCODE_WINDOW");
+ names.append(KEYCODE_GUIDE, "KEYCODE_GUIDE");
+ names.append(KEYCODE_DVR, "KEYCODE_DVR");
+ names.append(KEYCODE_BOOKMARK, "KEYCODE_BOOKMARK");
+ names.append(KEYCODE_CAPTIONS, "KEYCODE_CAPTIONS");
+ names.append(KEYCODE_SETTINGS, "KEYCODE_SETTINGS");
+ names.append(KEYCODE_TV_POWER, "KEYCODE_TV_POWER");
+ names.append(KEYCODE_TV_INPUT, "KEYCODE_TV_INPUT");
+ names.append(KEYCODE_STB_INPUT, "KEYCODE_STB_INPUT");
+ names.append(KEYCODE_STB_POWER, "KEYCODE_STB_POWER");
+ names.append(KEYCODE_AVR_POWER, "KEYCODE_AVR_POWER");
+ names.append(KEYCODE_AVR_INPUT, "KEYCODE_AVR_INPUT");
+ names.append(KEYCODE_PROG_RED, "KEYCODE_PROG_RED");
+ names.append(KEYCODE_PROG_GREEN, "KEYCODE_PROG_GREEN");
+ names.append(KEYCODE_PROG_YELLOW, "KEYCODE_PROG_YELLOW");
+ names.append(KEYCODE_PROG_BLUE, "KEYCODE_PROG_BLUE");
+ names.append(KEYCODE_APP_SWITCH, "KEYCODE_APP_SWITCH");
+ names.append(KEYCODE_BUTTON_1, "KEYCODE_BUTTON_1");
+ names.append(KEYCODE_BUTTON_2, "KEYCODE_BUTTON_2");
+ names.append(KEYCODE_BUTTON_3, "KEYCODE_BUTTON_3");
+ names.append(KEYCODE_BUTTON_4, "KEYCODE_BUTTON_4");
+ names.append(KEYCODE_BUTTON_5, "KEYCODE_BUTTON_5");
+ names.append(KEYCODE_BUTTON_6, "KEYCODE_BUTTON_6");
+ names.append(KEYCODE_BUTTON_7, "KEYCODE_BUTTON_7");
+ names.append(KEYCODE_BUTTON_8, "KEYCODE_BUTTON_8");
+ names.append(KEYCODE_BUTTON_9, "KEYCODE_BUTTON_9");
+ names.append(KEYCODE_BUTTON_10, "KEYCODE_BUTTON_10");
+ names.append(KEYCODE_BUTTON_11, "KEYCODE_BUTTON_11");
+ names.append(KEYCODE_BUTTON_12, "KEYCODE_BUTTON_12");
+ names.append(KEYCODE_BUTTON_13, "KEYCODE_BUTTON_13");
+ names.append(KEYCODE_BUTTON_14, "KEYCODE_BUTTON_14");
+ names.append(KEYCODE_BUTTON_15, "KEYCODE_BUTTON_15");
+ names.append(KEYCODE_BUTTON_16, "KEYCODE_BUTTON_16");
};
// Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1180,6 +1182,8 @@
private KeyEvent mNext;
private boolean mRecycled;
+ private int mDeviceId;
+ private int mSource;
private int mMetaState;
private int mAction;
private int mKeyCode;
@@ -1248,14 +1252,7 @@
}
static {
- if (META_SYMBOLIC_NAMES.length != 32) {
- throw new IllegalStateException(
- "META_SYMBOLIC_NAMES array should contain exactly 32 entries.");
- }
- if (KEYCODE_SYMBOLIC_NAMES.length != LAST_KEYCODE + 1) {
- throw new IllegalStateException(
- "KEYCODE_SYMBOLIC_NAMES array is out of sync with the keycode constants.");
- }
+ populateKeycodeSymbolicNames();
}
private KeyEvent() {
@@ -1651,6 +1648,66 @@
return native_hasDefaultAction(mKeyCode);
}
+ /**
+ * Returns true if the specified keycode is a gamepad button.
+ * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
+ */
+ public static final boolean isGamepadButton(int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BUTTON_A:
+ case KeyEvent.KEYCODE_BUTTON_B:
+ case KeyEvent.KEYCODE_BUTTON_C:
+ case KeyEvent.KEYCODE_BUTTON_X:
+ case KeyEvent.KEYCODE_BUTTON_Y:
+ case KeyEvent.KEYCODE_BUTTON_Z:
+ case KeyEvent.KEYCODE_BUTTON_L1:
+ case KeyEvent.KEYCODE_BUTTON_R1:
+ case KeyEvent.KEYCODE_BUTTON_L2:
+ case KeyEvent.KEYCODE_BUTTON_R2:
+ case KeyEvent.KEYCODE_BUTTON_THUMBL:
+ case KeyEvent.KEYCODE_BUTTON_THUMBR:
+ case KeyEvent.KEYCODE_BUTTON_START:
+ case KeyEvent.KEYCODE_BUTTON_SELECT:
+ case KeyEvent.KEYCODE_BUTTON_MODE:
+ case KeyEvent.KEYCODE_BUTTON_1:
+ case KeyEvent.KEYCODE_BUTTON_2:
+ case KeyEvent.KEYCODE_BUTTON_3:
+ case KeyEvent.KEYCODE_BUTTON_4:
+ case KeyEvent.KEYCODE_BUTTON_5:
+ case KeyEvent.KEYCODE_BUTTON_6:
+ case KeyEvent.KEYCODE_BUTTON_7:
+ case KeyEvent.KEYCODE_BUTTON_8:
+ case KeyEvent.KEYCODE_BUTTON_9:
+ case KeyEvent.KEYCODE_BUTTON_10:
+ case KeyEvent.KEYCODE_BUTTON_11:
+ case KeyEvent.KEYCODE_BUTTON_12:
+ case KeyEvent.KEYCODE_BUTTON_13:
+ case KeyEvent.KEYCODE_BUTTON_14:
+ case KeyEvent.KEYCODE_BUTTON_15:
+ case KeyEvent.KEYCODE_BUTTON_16:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final int getDeviceId() {
+ return mDeviceId;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final int getSource() {
+ return mSource;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final void setSource(int source) {
+ mSource = source;
+ }
/**
* <p>Returns the state of the meta keys.</p>
@@ -2535,7 +2592,7 @@
/**
* Returns a string that represents the symbolic name of the specified action
- * such as "ACTION_DOWN", or "35" (if unknown).
+ * such as "ACTION_DOWN", or an equivalent numeric constant such as "35" if unknown.
*
* @param action The action.
* @return The symbolic name of the specified action.
@@ -2556,52 +2613,51 @@
/**
* Returns a string that represents the symbolic name of the specified keycode
- * such as "KEYCODE_A", "KEYCODE_DPAD_UP", or "1001" (if unknown).
+ * such as "KEYCODE_A", "KEYCODE_DPAD_UP", or an equivalent numeric constant
+ * such as "1001" if unknown.
*
* @param keyCode The key code.
* @return The symbolic name of the specified keycode.
*
* @see KeyCharacterMap#getDisplayLabel
- * @hide
*/
public static String keyCodeToString(int keyCode) {
- if (keyCode >= 0 && keyCode < KEYCODE_SYMBOLIC_NAMES.length) {
- return KEYCODE_SYMBOLIC_NAMES[keyCode];
- }
- return Integer.toString(keyCode);
+ String symbolicName = KEYCODE_SYMBOLIC_NAMES.get(keyCode);
+ return symbolicName != null ? symbolicName : Integer.toString(keyCode);
}
/**
- * Gets a keycode by its symbolic name such as "KEYCODE_A" or "1001" (if unknown).
+ * Gets a keycode by its symbolic name such as "KEYCODE_A" or an equivalent
+ * numeric constant such as "1001".
*
* @param symbolicName The symbolic name of the keycode.
- * @return The keycode or -1 if not found.
+ * @return The keycode or {@link #KEYCODE_UNKNOWN} if not found.
* @see #keycodeToString
- * @hide
*/
public static int keyCodeFromString(String symbolicName) {
if (symbolicName == null) {
throw new IllegalArgumentException("symbolicName must not be null");
}
- final int count = KEYCODE_SYMBOLIC_NAMES.length;
+ final int count = KEYCODE_SYMBOLIC_NAMES.size();
for (int i = 0; i < count; i++) {
- if (symbolicName.equals(KEYCODE_SYMBOLIC_NAMES[i])) {
+ if (symbolicName.equals(KEYCODE_SYMBOLIC_NAMES.valueAt(i))) {
return i;
}
}
try {
- return Integer.parseInt(symbolicName,10);
+ return Integer.parseInt(symbolicName, 10);
} catch (NumberFormatException ex) {
- return -1;
+ return KEYCODE_UNKNOWN;
}
}
/**
* Returns a string that represents the symbolic name of the specified combined meta
* key modifier state flags such as "0", "META_SHIFT_ON",
- * "META_ALT_ON|META_SHIFT_ON" or "0x10000000" (if unknown).
+ * "META_ALT_ON|META_SHIFT_ON" or an equivalent numeric constant such as "0x10000000"
+ * if unknown.
*
* @param metaState The meta state.
* @return The symbolic name of the specified combined meta state flags.
@@ -2651,8 +2707,8 @@
}
private KeyEvent(Parcel in) {
- readBaseFromParcel(in);
-
+ mDeviceId = in.readInt();
+ mSource = in.readInt();
mAction = in.readInt();
mKeyCode = in.readInt();
mRepeatCount = in.readInt();
@@ -2665,9 +2721,9 @@
public void writeToParcel(Parcel out, int flags) {
out.writeInt(PARCEL_TOKEN_KEY_EVENT);
-
- writeBaseToParcel(out);
-
+
+ out.writeInt(mDeviceId);
+ out.writeInt(mSource);
out.writeInt(mAction);
out.writeInt(mKeyCode);
out.writeInt(mRepeatCount);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 5db4895..cc37a28 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -20,6 +20,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.util.SparseArray;
/**
* Object used to report movement (mouse, pen, finger, trackball) events. This
@@ -102,7 +103,7 @@
* </p>
*/
public final class MotionEvent extends InputEvent implements Parcelable {
- private static final long MS_PER_NS = 1000000;
+ private static final long NS_PER_MS = 1000000;
private static final boolean TRACK_RECYCLED_LOCATION = false;
/**
@@ -156,7 +157,15 @@
* {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
*/
public static final int ACTION_POINTER_UP = 6;
-
+
+ /**
+ * Constant for {@link #getAction}: A change happened but the pointer
+ * is not down (unlike {@link #ACTION_MOVE}). The motion contains the most
+ * recent point, as well as any intermediate points since the last
+ * hover move event.
+ */
+ public static final int ACTION_HOVER_MOVE = 7;
+
/**
* Bits in the action code that represent a pointer index, used with
* {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting
@@ -261,123 +270,694 @@
*/
public static final int EDGE_RIGHT = 0x00000008;
- /*
- * Offset for the sample's X coordinate.
+ /**
+ * Constant used to identify the X axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the absolute X screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * <li>For a touch pad, reports the absolute X surface position of the center of the touch
+ * contact area. The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * <li>For a mouse, reports the absolute X screen position of the mouse pointer.
+ * The units are display pixels.
+ * <li>For a trackball, reports the relative horizontal displacement of the trackball.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * <li>For a joystick, reports the absolute X position of the joystick.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p>
+ *
+ * @see #getX(int)
+ * @see #getHistoricalX(int, int)
+ * @see MotionEvent.PointerCoords#x
+ * @see InputDevice#getMotionRange
*/
- static private final int SAMPLE_X = 0;
-
- /*
- * Offset for the sample's Y coordinate.
- */
- static private final int SAMPLE_Y = 1;
-
- /*
- * Offset for the sample's pressure.
- */
- static private final int SAMPLE_PRESSURE = 2;
-
- /*
- * Offset for the sample's size
- */
- static private final int SAMPLE_SIZE = 3;
-
- /*
- * Offset for the sample's touch major axis length.
- */
- static private final int SAMPLE_TOUCH_MAJOR = 4;
+ public static final int AXIS_X = 0;
- /*
- * Offset for the sample's touch minor axis length.
+ /**
+ * Constant used to identify the Y axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the absolute Y screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * <li>For a touch pad, reports the absolute Y surface position of the center of the touch
+ * contact area. The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * <li>For a mouse, reports the absolute Y screen position of the mouse pointer.
+ * The units are display pixels.
+ * <li>For a trackball, reports the relative vertical displacement of the trackball.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * <li>For a joystick, reports the absolute Y position of the joystick.
+ * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).
+ * </ul>
+ * </p>
+ *
+ * @see #getY(int)
+ * @see #getHistoricalY(int, int)
+ * @see MotionEvent.PointerCoords#y
+ * @see InputDevice#getMotionRange
*/
- static private final int SAMPLE_TOUCH_MINOR = 5;
-
- /*
- * Offset for the sample's tool major axis length.
- */
- static private final int SAMPLE_TOOL_MAJOR = 6;
+ public static final int AXIS_Y = 1;
- /*
- * Offset for the sample's tool minor axis length.
+ /**
+ * Constant used to identify the Pressure axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the approximate pressure applied to the surface
+ * by a finger or other tool. The value is normalized to a range from
+ * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1
+ * may be generated depending on the calibration of the input device.
+ * <li>For a trackball, the value is set to 1 if the trackball button is pressed
+ * or 0 otherwise.
+ * <li>For a mouse, the value is set to 1 if the primary mouse button is pressed
+ * or 0 otherwise.
+ * </ul>
+ * </p>
+ *
+ * @see #getPressure(int)
+ * @see #getHistoricalPressure(int, int)
+ * @see MotionEvent.PointerCoords#pressure
+ * @see InputDevice#getMotionRange
*/
- static private final int SAMPLE_TOOL_MINOR = 7;
-
- /*
- * Offset for the sample's orientation.
- */
- static private final int SAMPLE_ORIENTATION = 8;
+ public static final int AXIS_PRESSURE = 2;
- /*
- * Number of data items for each sample.
+ /**
+ * Constant used to identify the Size axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the approximate size of the contact area in
+ * relation to the maximum detectable size for the device. The value is normalized
+ * to a range from 0 (smallest detectable size) to 1 (largest detectable size),
+ * although it is not a linear scale. This value is of limited use.
+ * To obtain calibrated size information, use
+ * {@link #AXIS_TOUCH_MAJOR} or {@link #AXIS_TOOL_MAJOR}.
+ * </ul>
+ * </p>
+ *
+ * @see #getSize(int)
+ * @see #getHistoricalSize(int, int)
+ * @see MotionEvent.PointerCoords#size
+ * @see InputDevice#getMotionRange
*/
- static private final int NUM_SAMPLE_DATA = 9;
-
- /*
- * Minimum number of pointers for which to reserve space when allocating new
- * motion events. This is explicitly not a bound on the maximum number of pointers.
+ public static final int AXIS_SIZE = 3;
+
+ /**
+ * Constant used to identify the TouchMajor axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * <li>For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p>
+ *
+ * @see #getTouchMajor(int)
+ * @see #getHistoricalTouchMajor(int, int)
+ * @see MotionEvent.PointerCoords#touchMajor
+ * @see InputDevice#getMotionRange
*/
- static private final int BASE_AVAIL_POINTERS = 5;
-
- /*
- * Minimum number of samples for which to reserve space when allocating new motion events.
+ public static final int AXIS_TOUCH_MAJOR = 4;
+
+ /**
+ * Constant used to identify the TouchMinor axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * <li>For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p>
+ *
+ * @see #getTouchMinor(int)
+ * @see #getHistoricalTouchMinor(int, int)
+ * @see MotionEvent.PointerCoords#touchMinor
+ * @see InputDevice#getMotionRange
*/
- static private final int BASE_AVAIL_SAMPLES = 8;
-
+ public static final int AXIS_TOUCH_MINOR = 5;
+
+ /**
+ * Constant used to identify the ToolMajor axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * <li>For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p><p>
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ * </p>
+ *
+ * @see #getToolMajor(int)
+ * @see #getHistoricalToolMajor(int, int)
+ * @see MotionEvent.PointerCoords#toolMajor
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_TOOL_MAJOR = 6;
+
+ /**
+ * Constant used to identify the ToolMinor axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * <li>For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p><p>
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ * </p>
+ *
+ * @see #getToolMinor(int)
+ * @see #getHistoricalToolMinor(int, int)
+ * @see MotionEvent.PointerCoords#toolMinor
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_TOOL_MINOR = 7;
+
+ /**
+ * Constant used to identify the Orientation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the orientation of the finger
+ * or tool in radians relative to the vertical plane of the device.
+ * An angle of 0 radians indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation. A positive angle
+ * indicates that the major axis of contact is oriented to the right. A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
+ * (finger pointing fully right).
+ * </ul>
+ * </p>
+ *
+ * @see #getOrientation(int)
+ * @see #getHistoricalOrientation(int, int)
+ * @see MotionEvent.PointerCoords#orientation
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_ORIENTATION = 8;
+
+ /**
+ * Constant used to identify the Vertical Scroll axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a mouse, reports the relative movement of the vertical scroll wheel.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * </ul>
+ * </p><p>
+ * This axis should be used to scroll views vertically.
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_VSCROLL = 9;
+
+ /**
+ * Constant used to identify the Horizontal Scroll axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a mouse, reports the relative movement of the horizontal scroll wheel.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p><p>
+ * This axis should be used to scroll views horizontally.
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HSCROLL = 10;
+
+ /**
+ * Constant used to identify the Z axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute Z position of the joystick.
+ * The value is normalized to a range from -1.0 (high) to 1.0 (low).
+ * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute X position of the second joystick instead.</em>
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_Z = 11;
+
+ /**
+ * Constant used to identify the X Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the X axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RX = 12;
+
+ /**
+ * Constant used to identify the Y Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the Y axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RY = 13;
+
+ /**
+ * Constant used to identify the Z Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the Z axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute Y position of the second joystick instead.</em>
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RZ = 14;
+
+ /**
+ * Constant used to identify the Hat X axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute X position of the directional hat control.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HAT_X = 15;
+
+ /**
+ * Constant used to identify the Hat Y axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute Y position of the directional hat control.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HAT_Y = 16;
+
+ /**
+ * Constant used to identify the Left Trigger axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the left trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_LTRIGGER = 17;
+
+ /**
+ * Constant used to identify the Right Trigger axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the right trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RTRIGGER = 18;
+
+ /**
+ * Constant used to identify the Generic 1 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_1 = 32;
+
+ /**
+ * Constant used to identify the Generic 2 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_2 = 33;
+
+ /**
+ * Constant used to identify the Generic 3 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_3 = 34;
+
+ /**
+ * Constant used to identify the Generic 4 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_4 = 35;
+
+ /**
+ * Constant used to identify the Generic 5 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_5 = 36;
+
+ /**
+ * Constant used to identify the Generic 6 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_6 = 37;
+
+ /**
+ * Constant used to identify the Generic 7 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_7 = 38;
+
+ /**
+ * Constant used to identify the Generic 8 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_8 = 39;
+
+ /**
+ * Constant used to identify the Generic 9 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_9 = 40;
+
+ /**
+ * Constant used to identify the Generic 10 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_10 = 41;
+
+ /**
+ * Constant used to identify the Generic 11 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_11 = 42;
+
+ /**
+ * Constant used to identify the Generic 12 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_12 = 43;
+
+ /**
+ * Constant used to identify the Generic 13 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_13 = 44;
+
+ /**
+ * Constant used to identify the Generic 14 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_14 = 45;
+
+ /**
+ * Constant used to identify the Generic 15 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_15 = 46;
+
+ /**
+ * Constant used to identify the Generic 16 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_16 = 47;
+
+ // NOTE: If you add a new axis here you must also add it to:
+ // native/include/android/input.h
+ // frameworks/base/include/ui/KeycodeLabels.h
+
+ // Symbolic names of all axes.
+ private static final SparseArray<String> AXIS_SYMBOLIC_NAMES = new SparseArray<String>();
+ private static void populateAxisSymbolicNames() {
+ SparseArray<String> names = AXIS_SYMBOLIC_NAMES;
+ names.append(AXIS_X, "AXIS_X");
+ names.append(AXIS_Y, "AXIS_Y");
+ names.append(AXIS_PRESSURE, "AXIS_PRESSURE");
+ names.append(AXIS_SIZE, "AXIS_SIZE");
+ names.append(AXIS_TOUCH_MAJOR, "AXIS_TOUCH_MAJOR");
+ names.append(AXIS_TOUCH_MINOR, "AXIS_TOUCH_MINOR");
+ names.append(AXIS_TOOL_MAJOR, "AXIS_TOOL_MAJOR");
+ names.append(AXIS_TOOL_MINOR, "AXIS_TOOL_MINOR");
+ names.append(AXIS_ORIENTATION, "AXIS_ORIENTATION");
+ names.append(AXIS_VSCROLL, "AXIS_VSCROLL");
+ names.append(AXIS_HSCROLL, "AXIS_HSCROLL");
+ names.append(AXIS_Z, "AXIS_Z");
+ names.append(AXIS_RX, "AXIS_RX");
+ names.append(AXIS_RY, "AXIS_RY");
+ names.append(AXIS_RZ, "AXIS_RZ");
+ names.append(AXIS_HAT_X, "AXIS_HAT_X");
+ names.append(AXIS_HAT_Y, "AXIS_HAT_Y");
+ names.append(AXIS_LTRIGGER, "AXIS_LTRIGGER");
+ names.append(AXIS_RTRIGGER, "AXIS_RTRIGGER");
+ names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
+ names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
+ names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
+ names.append(AXIS_GENERIC_4, "AXIS_GENERIC_4");
+ names.append(AXIS_GENERIC_5, "AXIS_GENERIC_5");
+ names.append(AXIS_GENERIC_6, "AXIS_GENERIC_6");
+ names.append(AXIS_GENERIC_7, "AXIS_GENERIC_7");
+ names.append(AXIS_GENERIC_8, "AXIS_GENERIC_8");
+ names.append(AXIS_GENERIC_9, "AXIS_GENERIC_9");
+ names.append(AXIS_GENERIC_10, "AXIS_GENERIC_10");
+ names.append(AXIS_GENERIC_11, "AXIS_GENERIC_11");
+ names.append(AXIS_GENERIC_12, "AXIS_GENERIC_12");
+ names.append(AXIS_GENERIC_13, "AXIS_GENERIC_13");
+ names.append(AXIS_GENERIC_14, "AXIS_GENERIC_14");
+ names.append(AXIS_GENERIC_15, "AXIS_GENERIC_15");
+ names.append(AXIS_GENERIC_16, "AXIS_GENERIC_16");
+ }
+
+ static {
+ populateAxisSymbolicNames();
+ }
+
+ // Private value for history pos that obtains the current sample.
+ private static final int HISTORY_CURRENT = -0x80000000;
+
private static final int MAX_RECYCLED = 10;
private static final Object gRecyclerLock = new Object();
private static int gRecyclerUsed;
private static MotionEvent gRecyclerTop;
- private long mDownTimeNano;
- private int mAction;
- private float mXOffset;
- private float mYOffset;
- private float mXPrecision;
- private float mYPrecision;
- private int mEdgeFlags;
- private int mMetaState;
- private int mFlags;
-
- private int mNumPointers;
- private int mNumSamples;
-
- private int mLastDataSampleIndex;
- private int mLastEventTimeNanoSampleIndex;
-
- // Array of mNumPointers size of identifiers for each pointer of data.
- private int[] mPointerIdentifiers;
-
- // Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data.
- // Samples are ordered from oldest to newest.
- private float[] mDataSamples;
-
- // Array of mNumSamples size of event time stamps in nanoseconds.
- // Samples are ordered from oldest to newest.
- private long[] mEventTimeNanoSamples;
+ // Shared temporary objects used when translating coordinates supplied by
+ // the caller into single element PointerCoords and pointer id arrays.
+ // Must lock gTmpPointerCoords prior to use.
+ private static final PointerCoords[] gTmpPointerCoords =
+ new PointerCoords[] { new PointerCoords() };
+ private static final int[] gTmpPointerIds = new int[] { 0 /*always 0*/ };
+
+ // Pointer to the native MotionEvent object that contains the actual data.
+ private int mNativePtr;
private MotionEvent mNext;
private RuntimeException mRecycledLocation;
private boolean mRecycled;
- private native void nativeTransform(Matrix matrix);
+ private static native int nativeInitialize(int nativePtr,
+ int deviceId, int source, int action, int flags, int edgeFlags, int metaState,
+ float xOffset, float yOffset, float xPrecision, float yPrecision,
+ long downTimeNanos, long eventTimeNanos,
+ int pointerCount, int[] pointerIds, PointerCoords[] pointerCoords);
+ private static native int nativeCopy(int destNativePtr, int sourceNativePtr,
+ boolean keepHistory);
+ private static native void nativeDispose(int nativePtr);
+ private static native void nativeAddBatch(int nativePtr, long eventTimeNanos,
+ PointerCoords[] pointerCoords, int metaState);
- private MotionEvent(int pointerCount, int sampleCount) {
- mPointerIdentifiers = new int[pointerCount];
- mDataSamples = new float[pointerCount * sampleCount * NUM_SAMPLE_DATA];
- mEventTimeNanoSamples = new long[sampleCount];
+ private static native int nativeGetDeviceId(int nativePtr);
+ private static native int nativeGetSource(int nativePtr);
+ private static native int nativeSetSource(int nativePtr, int source);
+ private static native int nativeGetAction(int nativePtr);
+ private static native void nativeSetAction(int nativePtr, int action);
+ private static native int nativeGetFlags(int nativePtr);
+ private static native int nativeGetEdgeFlags(int nativePtr);
+ private static native void nativeSetEdgeFlags(int nativePtr, int action);
+ private static native int nativeGetMetaState(int nativePtr);
+ private static native void nativeOffsetLocation(int nativePtr, float deltaX, float deltaY);
+ private static native float nativeGetXPrecision(int nativePtr);
+ private static native float nativeGetYPrecision(int nativePtr);
+ private static native long nativeGetDownTimeNanos(int nativePtr);
+
+ private static native int nativeGetPointerCount(int nativePtr);
+ private static native int nativeGetPointerId(int nativePtr, int pointerIndex);
+ private static native int nativeFindPointerIndex(int nativePtr, int pointerId);
+
+ private static native int nativeGetHistorySize(int nativePtr);
+ private static native long nativeGetEventTimeNanos(int nativePtr, int historyPos);
+ private static native float nativeGetRawAxisValue(int nativePtr,
+ int axis, int pointerIndex, int historyPos);
+ private static native float nativeGetAxisValue(int nativePtr,
+ int axis, int pointerIndex, int historyPos);
+ private static native void nativeGetPointerCoords(int nativePtr,
+ int pointerIndex, int historyPos, PointerCoords outPointerCoords);
+
+ private static native void nativeScale(int nativePtr, float scale);
+ private static native void nativeTransform(int nativePtr, Matrix matrix);
+
+ private static native int nativeReadFromParcel(int nativePtr, Parcel parcel);
+ private static native void nativeWriteToParcel(int nativePtr, Parcel parcel);
+
+ private MotionEvent() {
}
- static private MotionEvent obtain(int pointerCount, int sampleCount) {
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mNativePtr != 0) {
+ nativeDispose(mNativePtr);
+ mNativePtr = 0;
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+
+ static private MotionEvent obtain() {
final MotionEvent ev;
synchronized (gRecyclerLock) {
ev = gRecyclerTop;
if (ev == null) {
- if (pointerCount < BASE_AVAIL_POINTERS) {
- pointerCount = BASE_AVAIL_POINTERS;
- }
- if (sampleCount < BASE_AVAIL_SAMPLES) {
- sampleCount = BASE_AVAIL_SAMPLES;
- }
- return new MotionEvent(pointerCount, sampleCount);
+ return new MotionEvent();
}
gRecyclerTop = ev.mNext;
gRecyclerUsed -= 1;
@@ -385,23 +965,9 @@
ev.mRecycledLocation = null;
ev.mRecycled = false;
ev.mNext = null;
-
- if (ev.mPointerIdentifiers.length < pointerCount) {
- ev.mPointerIdentifiers = new int[pointerCount];
- }
-
- if (ev.mEventTimeNanoSamples.length < sampleCount) {
- ev.mEventTimeNanoSamples = new long[sampleCount];
- }
-
- final int neededDataSamplesLength = pointerCount * sampleCount * NUM_SAMPLE_DATA;
- if (ev.mDataSamples.length < neededDataSamplesLength) {
- ev.mDataSamples = new float[neededDataSamplesLength];
- }
-
return ev;
}
-
+
/**
* Create a new MotionEvent, filling in all of the basic values that
* define the motion.
@@ -410,9 +976,7 @@
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param pointers The number of points that will be in this event.
* @param pointerIds An array of <em>pointers</em> values providing
* an identifier for each pointer.
@@ -434,34 +998,15 @@
int action, int pointers, int[] pointerIds, PointerCoords[] pointerCoords,
int metaState, float xPrecision, float yPrecision, int deviceId,
int edgeFlags, int source, int flags) {
- MotionEvent ev = obtain(pointers, 1);
- ev.mDeviceId = deviceId;
- ev.mSource = source;
- ev.mEdgeFlags = edgeFlags;
- ev.mDownTimeNano = downTime * MS_PER_NS;
- ev.mAction = action;
- ev.mFlags = flags;
- ev.mMetaState = metaState;
- ev.mXOffset = 0;
- ev.mYOffset = 0;
- ev.mXPrecision = xPrecision;
- ev.mYPrecision = yPrecision;
-
- ev.mNumPointers = pointers;
- ev.mNumSamples = 1;
-
- ev.mLastDataSampleIndex = 0;
- ev.mLastEventTimeNanoSampleIndex = 0;
-
- System.arraycopy(pointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
-
- ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
-
- ev.setPointerCoordsAtSampleIndex(0, pointerCoords);
-
+ MotionEvent ev = obtain();
+ ev.mNativePtr = nativeInitialize(ev.mNativePtr,
+ deviceId, source, action, flags, edgeFlags, metaState,
+ 0, 0, xPrecision, yPrecision,
+ downTime * NS_PER_MS, eventTime * NS_PER_MS,
+ pointers, pointerIds, pointerCoords);
return ev;
}
-
+
/**
* Create a new MotionEvent, filling in all of the basic values that
* define the motion.
@@ -470,9 +1015,7 @@
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
* @param pressure The current pressure of this event. The pressure generally
@@ -496,31 +1039,22 @@
static public MotionEvent obtain(long downTime, long eventTime, int action,
float x, float y, float pressure, float size, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
- MotionEvent ev = obtain(1, 1);
- ev.mDeviceId = deviceId;
- ev.mSource = InputDevice.SOURCE_UNKNOWN;
- ev.mEdgeFlags = edgeFlags;
- ev.mDownTimeNano = downTime * MS_PER_NS;
- ev.mAction = action;
- ev.mFlags = 0;
- ev.mMetaState = metaState;
- ev.mXOffset = 0;
- ev.mYOffset = 0;
- ev.mXPrecision = xPrecision;
- ev.mYPrecision = yPrecision;
-
- ev.mNumPointers = 1;
- ev.mNumSamples = 1;
-
- ev.mLastDataSampleIndex = 0;
- ev.mLastEventTimeNanoSampleIndex = 0;
-
- ev.mPointerIdentifiers[0] = 0;
-
- ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
-
- ev.setPointerCoordsAtSampleIndex(0, x, y, pressure, size);
- return ev;
+ synchronized (gTmpPointerCoords) {
+ final PointerCoords pc = gTmpPointerCoords[0];
+ pc.clear();
+ pc.x = x;
+ pc.y = y;
+ pc.pressure = pressure;
+ pc.size = size;
+
+ MotionEvent ev = obtain();
+ ev.mNativePtr = nativeInitialize(ev.mNativePtr,
+ deviceId, InputDevice.SOURCE_UNKNOWN, action, 0, edgeFlags, metaState,
+ 0, 0, xPrecision, yPrecision,
+ downTime * NS_PER_MS, eventTime * NS_PER_MS,
+ 1, gTmpPointerIds, gTmpPointerCoords);
+ return ev;
+ }
}
/**
@@ -531,9 +1065,7 @@
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param pointers The number of pointers that are active in this event.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
@@ -575,9 +1107,7 @@
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
* @param metaState The state of any meta / modifier keys that were in effect when
@@ -592,31 +1122,13 @@
/**
* Create a new MotionEvent, copying from an existing one.
*/
- static public MotionEvent obtain(MotionEvent o) {
- MotionEvent ev = obtain(o.mNumPointers, o.mNumSamples);
- ev.mDeviceId = o.mDeviceId;
- ev.mSource = o.mSource;
- ev.mEdgeFlags = o.mEdgeFlags;
- ev.mDownTimeNano = o.mDownTimeNano;
- ev.mAction = o.mAction;
- ev.mFlags = o.mFlags;
- ev.mMetaState = o.mMetaState;
- ev.mXOffset = o.mXOffset;
- ev.mYOffset = o.mYOffset;
- ev.mXPrecision = o.mXPrecision;
- ev.mYPrecision = o.mYPrecision;
- int numPointers = ev.mNumPointers = o.mNumPointers;
- int numSamples = ev.mNumSamples = o.mNumSamples;
-
- ev.mLastDataSampleIndex = o.mLastDataSampleIndex;
- ev.mLastEventTimeNanoSampleIndex = o.mLastEventTimeNanoSampleIndex;
-
- System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
-
- System.arraycopy(o.mEventTimeNanoSamples, 0, ev.mEventTimeNanoSamples, 0, numSamples);
-
- System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0,
- numPointers * numSamples * NUM_SAMPLE_DATA);
+ static public MotionEvent obtain(MotionEvent other) {
+ if (other == null) {
+ throw new IllegalArgumentException("other motion event must not be null");
+ }
+
+ MotionEvent ev = obtain();
+ ev.mNativePtr = nativeCopy(ev.mNativePtr, other.mNativePtr, true /*keepHistory*/);
return ev;
}
@@ -624,32 +1136,13 @@
* Create a new MotionEvent, copying from an existing one, but not including
* any historical point information.
*/
- static public MotionEvent obtainNoHistory(MotionEvent o) {
- MotionEvent ev = obtain(o.mNumPointers, 1);
- ev.mDeviceId = o.mDeviceId;
- ev.mSource = o.mSource;
- ev.mEdgeFlags = o.mEdgeFlags;
- ev.mDownTimeNano = o.mDownTimeNano;
- ev.mAction = o.mAction;
- o.mFlags = o.mFlags;
- ev.mMetaState = o.mMetaState;
- ev.mXOffset = o.mXOffset;
- ev.mYOffset = o.mYOffset;
- ev.mXPrecision = o.mXPrecision;
- ev.mYPrecision = o.mYPrecision;
-
- int numPointers = ev.mNumPointers = o.mNumPointers;
- ev.mNumSamples = 1;
-
- ev.mLastDataSampleIndex = 0;
- ev.mLastEventTimeNanoSampleIndex = 0;
-
- System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, numPointers);
-
- ev.mEventTimeNanoSamples[0] = o.mEventTimeNanoSamples[o.mLastEventTimeNanoSampleIndex];
-
- System.arraycopy(o.mDataSamples, o.mLastDataSampleIndex, ev.mDataSamples, 0,
- numPointers * NUM_SAMPLE_DATA);
+ static public MotionEvent obtainNoHistory(MotionEvent other) {
+ if (other == null) {
+ throw new IllegalArgumentException("other motion event must not be null");
+ }
+
+ MotionEvent ev = obtain();
+ ev.mNativePtr = nativeCopy(ev.mNativePtr, other.mNativePtr, false /*keepHistory*/);
return ev;
}
@@ -675,7 +1168,6 @@
synchronized (gRecyclerLock) {
if (gRecyclerUsed < MAX_RECYCLED) {
gRecyclerUsed++;
- mNumSamples = 0;
mNext = gRecyclerTop;
gRecyclerTop = this;
}
@@ -688,58 +1180,60 @@
* @hide
*/
public final void scale(float scale) {
- mXOffset *= scale;
- mYOffset *= scale;
- mXPrecision *= scale;
- mYPrecision *= scale;
-
- float[] history = mDataSamples;
- final int length = mNumPointers * mNumSamples * NUM_SAMPLE_DATA;
- for (int i = 0; i < length; i += NUM_SAMPLE_DATA) {
- history[i + SAMPLE_X] *= scale;
- history[i + SAMPLE_Y] *= scale;
- // no need to scale pressure
- history[i + SAMPLE_SIZE] *= scale; // TODO: square this?
- history[i + SAMPLE_TOUCH_MAJOR] *= scale;
- history[i + SAMPLE_TOUCH_MINOR] *= scale;
- history[i + SAMPLE_TOOL_MAJOR] *= scale;
- history[i + SAMPLE_TOOL_MINOR] *= scale;
- }
+ nativeScale(mNativePtr, scale);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final int getDeviceId() {
+ return nativeGetDeviceId(mNativePtr);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final int getSource() {
+ return nativeGetSource(mNativePtr);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final void setSource(int source) {
+ nativeSetSource(mNativePtr, source);
}
/**
- * Return the kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}. Consider using {@link #getActionMasked}
- * and {@link #getActionIndex} to retrieve the separate masked action
- * and pointer index.
+ * Return the kind of action being performed.
+ * Consider using {@link #getActionMasked} and {@link #getActionIndex} to retrieve
+ * the separate masked action and pointer index.
+ * @return The action, such as {@link #ACTION_DOWN} or
+ * the combination of {@link #ACTION_POINTER_DOWN} with a shifted pointer index.
*/
public final int getAction() {
- return mAction;
+ return nativeGetAction(mNativePtr);
}
/**
- * Return the masked action being performed, without pointer index
- * information. May be any of the actions: {@link #ACTION_DOWN},
- * {@link #ACTION_MOVE}, {@link #ACTION_UP}, {@link #ACTION_CANCEL},
- * {@link #ACTION_POINTER_DOWN}, or {@link #ACTION_POINTER_UP}.
- * Use {@link #getActionIndex} to return the index associated with
- * pointer actions.
+ * Return the masked action being performed, without pointer index information.
+ * Use {@link #getActionIndex} to return the index associated with pointer actions.
+ * @return The action, such as {@link #ACTION_DOWN} or {@link #ACTION_POINTER_DOWN}.
*/
public final int getActionMasked() {
- return mAction & ACTION_MASK;
+ return nativeGetAction(mNativePtr) & ACTION_MASK;
}
/**
* For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP}
* as returned by {@link #getActionMasked}, this returns the associated
- * pointer index. The index may be used with {@link #getPointerId(int)},
+ * pointer index.
+ * The index may be used with {@link #getPointerId(int)},
* {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)},
* and {@link #getSize(int)} to get information about the pointer that has
* gone down or up.
+ * @return The index associated with the action.
*/
public final int getActionIndex() {
- return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
+ return (nativeGetAction(mNativePtr) & ACTION_POINTER_INDEX_MASK)
+ >> ACTION_POINTER_INDEX_SHIFT;
}
/**
@@ -748,7 +1242,7 @@
* @see #FLAG_WINDOW_IS_OBSCURED
*/
public final int getFlags() {
- return mFlags;
+ return nativeGetFlags(mNativePtr);
}
/**
@@ -756,14 +1250,14 @@
* a stream of position events.
*/
public final long getDownTime() {
- return mDownTimeNano / MS_PER_NS;
+ return nativeGetDownTimeNanos(mNativePtr) / NS_PER_MS;
}
/**
* Returns the time (in ms) when this specific event was generated.
*/
public final long getEventTime() {
- return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] / MS_PER_NS;
+ return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT) / NS_PER_MS;
}
/**
@@ -773,79 +1267,110 @@
* @hide
*/
public final long getEventTimeNano() {
- return mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex];
+ return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT);
}
/**
* {@link #getX(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_X
*/
public final float getX() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_X] + mXOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT);
}
/**
* {@link #getY(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_Y
*/
public final float getY() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_Y] + mYOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT);
}
/**
* {@link #getPressure(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_PRESSURE
*/
public final float getPressure() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE];
+ return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, 0, HISTORY_CURRENT);
}
/**
* {@link #getSize(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_SIZE
*/
public final float getSize() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_SIZE];
+ return nativeGetAxisValue(mNativePtr, AXIS_SIZE, 0, HISTORY_CURRENT);
}
/**
* {@link #getTouchMajor(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_TOUCH_MAJOR
*/
public final float getTouchMajor() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_TOUCH_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, 0, HISTORY_CURRENT);
}
/**
* {@link #getTouchMinor(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_TOUCH_MINOR
*/
public final float getTouchMinor() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_TOUCH_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, 0, HISTORY_CURRENT);
}
/**
* {@link #getToolMajor(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_TOOL_MAJOR
*/
public final float getToolMajor() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_TOOL_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, 0, HISTORY_CURRENT);
}
/**
* {@link #getToolMinor(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_TOOL_MINOR
*/
public final float getToolMinor() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_TOOL_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, 0, HISTORY_CURRENT);
}
-
+
/**
* {@link #getOrientation(int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @see #AXIS_ORIENTATION
*/
public final float getOrientation() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_ORIENTATION];
+ return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, 0, HISTORY_CURRENT);
+ }
+
+ /**
+ * {@link #getAxisValue(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ *
+ * @param axis The axis identifier for the axis value to retrieve.
+ *
+ * @see #AXIS_X
+ * @see #AXIS_Y
+ */
+ public final float getAxisValue(int axis) {
+ return nativeGetAxisValue(mNativePtr, axis, 0, HISTORY_CURRENT);
}
/**
@@ -853,7 +1378,7 @@
* >= 1.
*/
public final int getPointerCount() {
- return mNumPointers;
+ return nativeGetPointerCount(mNativePtr);
}
/**
@@ -865,7 +1390,7 @@
* (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
public final int getPointerId(int pointerIndex) {
- return mPointerIdentifiers[pointerIndex];
+ return nativeGetPointerId(mNativePtr, pointerIndex);
}
/**
@@ -877,14 +1402,7 @@
* that pointer identifier.
*/
public final int findPointerIndex(int pointerId) {
- int i = mNumPointers;
- while (i > 0) {
- i--;
- if (mPointerIdentifiers[i] == pointerId) {
- return i;
- }
- }
- return -1;
+ return nativeFindPointerIndex(mNativePtr, pointerId);
}
/**
@@ -895,10 +1413,11 @@
* value may have a fraction for input devices that are sub-pixel precise.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_X
*/
public final float getX(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -909,10 +1428,11 @@
* value may have a fraction for input devices that are sub-pixel precise.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_Y
*/
public final float getY(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_Y, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -925,10 +1445,11 @@
* the input device.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_PRESSURE
*/
public final float getPressure(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
+ return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -942,10 +1463,11 @@
* determine fat touch events.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_SIZE
*/
public final float getSize(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_SIZE];
+ return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -955,10 +1477,11 @@
* identifier for this index).
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_TOUCH_MAJOR
*/
public final float getTouchMajor(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -968,10 +1491,11 @@
* identifier for this index).
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_TOUCH_MINOR
*/
public final float getTouchMinor(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -983,10 +1507,11 @@
* touching the device independent of its actual touch area at the point of contact.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_TOOL_MAJOR
*/
public final float getToolMajor(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, pointerIndex, HISTORY_CURRENT);
}
/**
@@ -998,17 +1523,18 @@
* touching the device independent of its actual touch area at the point of contact.
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_TOOL_MINOR
*/
public final float getToolMinor(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, pointerIndex, HISTORY_CURRENT);
}
/**
* Returns the orientation of the touch area and tool area in radians clockwise from vertical
* for the given pointer <em>index</em> (use {@link #getPointerId(int)} to find the pointer
* identifier for this index).
- * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * An angle of 0 radians indicates that the major axis of contact is oriented
* upwards, is perfectly circular or is of unknown orientation. A positive angle
* indicates that the major axis of contact is oriented to the right. A negative angle
* indicates that the major axis of contact is oriented to the left.
@@ -1016,12 +1542,29 @@
* (finger pointing fully right).
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
+ *
+ * @see #AXIS_ORIENTATION
*/
public final float getOrientation(int pointerIndex) {
- return mDataSamples[mLastDataSampleIndex
- + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
+ return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, HISTORY_CURRENT);
}
-
+
+ /**
+ * Returns the value of the requested axis for the given pointer <em>index</em>
+ * (use {@link #getPointerId(int)} to find the pointer identifier for this index).
+ *
+ * @param axis The axis identifier for the axis value to retrieve.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @return The value of the axis, or 0 if the axis is not available.
+ *
+ * @see #AXIS_X
+ * @see #AXIS_Y
+ */
+ public final float getAxisValue(int axis, int pointerIndex) {
+ return nativeGetAxisValue(mNativePtr, axis, pointerIndex, HISTORY_CURRENT);
+ }
+
/**
* Populates a {@link PointerCoords} object with pointer coordinate data for
* the specified pointer index.
@@ -1029,10 +1572,11 @@
* @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
* (the first pointer that is down) to {@link #getPointerCount()}-1.
* @param outPointerCoords The pointer coordinate object to populate.
+ *
+ * @see PointerCoords
*/
public final void getPointerCoords(int pointerIndex, PointerCoords outPointerCoords) {
- final int sampleIndex = mLastDataSampleIndex + pointerIndex * NUM_SAMPLE_DATA;
- getPointerCoordsAtSampleIndex(sampleIndex, outPointerCoords);
+ nativeGetPointerCoords(mNativePtr, pointerIndex, HISTORY_CURRENT, outPointerCoords);
}
/**
@@ -1046,7 +1590,7 @@
* @see KeyEvent#getMetaState()
*/
public final int getMetaState() {
- return mMetaState;
+ return nativeGetMetaState(mNativePtr);
}
/**
@@ -1054,39 +1598,49 @@
* events on the screen, this is the original location of the event
* on the screen, before it had been adjusted for the containing window
* and views.
+ *
+ * @see getX()
+ * @see #AXIS_X
*/
public final float getRawX() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_X];
+ return nativeGetRawAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT);
}
-
+
/**
* Returns the original raw Y coordinate of this event. For touch
* events on the screen, this is the original location of the event
* on the screen, before it had been adjusted for the containing window
* and views.
+ *
+ * @see getY()
+ * @see #AXIS_Y
*/
public final float getRawY() {
- return mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
+ return nativeGetRawAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT);
}
/**
* Return the precision of the X coordinates being reported. You can
- * multiple this number with {@link #getX} to find the actual hardware
+ * multiply this number with {@link #getX} to find the actual hardware
* value of the X coordinate.
* @return Returns the precision of X coordinates being reported.
+ *
+ * @see #AXIS_X
*/
public final float getXPrecision() {
- return mXPrecision;
+ return nativeGetXPrecision(mNativePtr);
}
/**
* Return the precision of the Y coordinates being reported. You can
- * multiple this number with {@link #getY} to find the actual hardware
+ * multiply this number with {@link #getY} to find the actual hardware
* value of the Y coordinate.
* @return Returns the precision of Y coordinates being reported.
+ *
+ * @see #AXIS_Y
*/
public final float getYPrecision() {
- return mYPrecision;
+ return nativeGetYPrecision(mNativePtr);
}
/**
@@ -1098,7 +1652,7 @@
* @return Returns the number of historical points in the event.
*/
public final int getHistorySize() {
- return mLastEventTimeNanoSampleIndex;
+ return nativeGetHistorySize(mNativePtr);
}
/**
@@ -1112,81 +1666,161 @@
* @see #getEventTime
*/
public final long getHistoricalEventTime(int pos) {
- return mEventTimeNanoSamples[pos] / MS_PER_NS;
+ return nativeGetEventTimeNanos(mNativePtr, pos) / NS_PER_MS;
}
/**
- * {@link #getHistoricalX(int)} for the first pointer index (may be an
+ * {@link #getHistoricalX(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getX()
+ * @see #AXIS_X
*/
public final float getHistoricalX(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_X, 0, pos);
}
/**
- * {@link #getHistoricalY(int)} for the first pointer index (may be an
+ * {@link #getHistoricalY(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getY()
+ * @see #AXIS_Y
*/
public final float getHistoricalY(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_Y, 0, pos);
}
/**
- * {@link #getHistoricalPressure(int)} for the first pointer index (may be an
+ * {@link #getHistoricalPressure(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getPressure()
+ * @see #AXIS_PRESSURE
*/
public final float getHistoricalPressure(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
+ return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, 0, pos);
}
/**
- * {@link #getHistoricalSize(int)} for the first pointer index (may be an
+ * {@link #getHistoricalSize(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getSize()
+ * @see #AXIS_SIZE
*/
public final float getHistoricalSize(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_SIZE];
+ return nativeGetAxisValue(mNativePtr, AXIS_SIZE, 0, pos);
}
/**
- * {@link #getHistoricalTouchMajor(int)} for the first pointer index (may be an
+ * {@link #getHistoricalTouchMajor(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getTouchMajor()
+ * @see #AXIS_TOUCH_MAJOR
*/
public final float getHistoricalTouchMajor(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, 0, pos);
}
/**
- * {@link #getHistoricalTouchMinor(int)} for the first pointer index (may be an
+ * {@link #getHistoricalTouchMinor(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getTouchMinor()
+ * @see #AXIS_TOUCH_MINOR
*/
public final float getHistoricalTouchMinor(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, 0, pos);
}
/**
- * {@link #getHistoricalToolMajor(int)} for the first pointer index (may be an
+ * {@link #getHistoricalToolMajor(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getToolMajor()
+ * @see #AXIS_TOOL_MAJOR
*/
public final float getHistoricalToolMajor(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, 0, pos);
}
/**
- * {@link #getHistoricalToolMinor(int)} for the first pointer index (may be an
+ * {@link #getHistoricalToolMinor(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getToolMinor()
+ * @see #AXIS_TOOL_MINOR
*/
public final float getHistoricalToolMinor(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, 0, pos);
}
/**
- * {@link #getHistoricalOrientation(int)} for the first pointer index (may be an
+ * {@link #getHistoricalOrientation(int, int)} for the first pointer index (may be an
* arbitrary pointer identifier).
+ *
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getOrientation()
+ * @see #AXIS_ORIENTATION
*/
public final float getHistoricalOrientation(int pos) {
- return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
+ return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, 0, pos);
}
-
+
+ /**
+ * {@link #getHistoricalAxisValue(int, int, int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ *
+ * @param axis The axis identifier for the axis value to retrieve.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getAxisValue(int)
+ * @see #AXIS_X
+ * @see #AXIS_Y
+ */
+ public final float getHistoricalAxisValue(int axis, int pos) {
+ return nativeGetAxisValue(mNativePtr, axis, 0, pos);
+ }
+
/**
* Returns a historical X coordinate, as per {@link #getX(int)}, that
* occurred between this event and the previous event for the given pointer.
@@ -1198,11 +1832,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getX
+ * @see #getX(int)
+ * @see #AXIS_X
*/
public final float getHistoricalX(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_X] + mXOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, pos);
}
/**
@@ -1216,11 +1850,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getY
+ * @see #getY(int)
+ * @see #AXIS_Y
*/
public final float getHistoricalY(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_Y] + mYOffset;
+ return nativeGetAxisValue(mNativePtr, AXIS_Y, pointerIndex, pos);
}
/**
@@ -1234,11 +1868,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getPressure
+ * @see #getPressure(int)
+ * @see #AXIS_PRESSURE
*/
public final float getHistoricalPressure(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_PRESSURE];
+ return nativeGetAxisValue(mNativePtr, AXIS_PRESSURE, pointerIndex, pos);
}
/**
@@ -1252,11 +1886,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getSize
+ * @see #getSize(int)
+ * @see #AXIS_SIZE
*/
public final float getHistoricalSize(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_SIZE];
+ return nativeGetAxisValue(mNativePtr, AXIS_SIZE, pointerIndex, pos);
}
/**
@@ -1270,11 +1904,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getTouchMajor
+ * @see #getTouchMajor(int)
+ * @see #AXIS_TOUCH_MAJOR
*/
public final float getHistoricalTouchMajor(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MAJOR, pointerIndex, pos);
}
/**
@@ -1288,11 +1922,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getTouchMinor
+ * @see #getTouchMinor(int)
+ * @see #AXIS_TOUCH_MINOR
*/
public final float getHistoricalTouchMinor(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOUCH_MINOR, pointerIndex, pos);
}
/**
@@ -1306,11 +1940,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getToolMajor
+ * @see #getToolMajor(int)
+ * @see #AXIS_TOOL_MAJOR
*/
public final float getHistoricalToolMajor(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MAJOR, pointerIndex, pos);
}
/**
@@ -1324,11 +1958,11 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getToolMinor
+ * @see #getToolMinor(int)
+ * @see #AXIS_TOOL_MINOR
*/
public final float getHistoricalToolMinor(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ return nativeGetAxisValue(mNativePtr, AXIS_TOOL_MINOR, pointerIndex, pos);
}
/**
@@ -1342,11 +1976,30 @@
* {@link #getHistorySize}
*
* @see #getHistorySize
- * @see #getOrientation
+ * @see #getOrientation(int)
+ * @see #AXIS_ORIENTATION
*/
public final float getHistoricalOrientation(int pointerIndex, int pos) {
- return mDataSamples[(pos * mNumPointers + pointerIndex)
- * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
+ return nativeGetAxisValue(mNativePtr, AXIS_ORIENTATION, pointerIndex, pos);
+ }
+
+ /**
+ * Returns the historical value of the requested axis, as per {@link #getAxisValue(int, int)},
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param axis The axis identifier for the axis value to retrieve.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ * @return The value of the axis, or 0 if the axis is not available.
+ *
+ * @see #AXIS_X
+ * @see #AXIS_Y
+ */
+ public final float getHistoricalAxisValue(int axis, int pointerIndex, int pos) {
+ return nativeGetAxisValue(mNativePtr, axis, pointerIndex, pos);
}
/**
@@ -1363,11 +2016,11 @@
*
* @see #getHistorySize
* @see #getPointerCoords
+ * @see PointerCoords
*/
public final void getHistoricalPointerCoords(int pointerIndex, int pos,
PointerCoords outPointerCoords) {
- final int sampleIndex = (pos * mNumPointers + pointerIndex) * NUM_SAMPLE_DATA;
- getPointerCoordsAtSampleIndex(sampleIndex, outPointerCoords);
+ nativeGetPointerCoords(mNativePtr, pointerIndex, pos, outPointerCoords);
}
/**
@@ -1381,10 +2034,9 @@
* @see #EDGE_BOTTOM
*/
public final int getEdgeFlags() {
- return mEdgeFlags;
+ return nativeGetEdgeFlags(mNativePtr);
}
-
/**
* Sets the bitfield indicating which edges, if any, were touched by this
* MotionEvent.
@@ -1392,14 +2044,14 @@
* @see #getEdgeFlags()
*/
public final void setEdgeFlags(int flags) {
- mEdgeFlags = flags;
+ nativeSetEdgeFlags(mNativePtr, flags);
}
/**
* Sets this event's action.
*/
public final void setAction(int action) {
- mAction = action;
+ nativeSetAction(mNativePtr, action);
}
/**
@@ -1408,8 +2060,7 @@
* @param deltaY Amount to add to the current Y coordinate of the event.
*/
public final void offsetLocation(float deltaX, float deltaY) {
- mXOffset += deltaX;
- mYOffset += deltaY;
+ nativeOffsetLocation(mNativePtr, deltaX, deltaY);
}
/**
@@ -1420,10 +2071,9 @@
* @param y New absolute Y location.
*/
public final void setLocation(float x, float y) {
- final float[] dataSamples = mDataSamples;
- final int lastDataSampleIndex = mLastDataSampleIndex;
- mXOffset = x - dataSamples[lastDataSampleIndex + SAMPLE_X];
- mYOffset = y - dataSamples[lastDataSampleIndex + SAMPLE_Y];
+ float oldX = getX();
+ float oldY = getY();
+ nativeOffsetLocation(mNativePtr, x - oldX, y - oldY);
}
/**
@@ -1436,86 +2086,15 @@
throw new IllegalArgumentException("matrix must not be null");
}
- nativeTransform(matrix);
- }
-
- private final void getPointerCoordsAtSampleIndex(int sampleIndex,
- PointerCoords outPointerCoords) {
- final float[] dataSamples = mDataSamples;
- outPointerCoords.x = dataSamples[sampleIndex + SAMPLE_X] + mXOffset;
- outPointerCoords.y = dataSamples[sampleIndex + SAMPLE_Y] + mYOffset;
- outPointerCoords.pressure = dataSamples[sampleIndex + SAMPLE_PRESSURE];
- outPointerCoords.size = dataSamples[sampleIndex + SAMPLE_SIZE];
- outPointerCoords.touchMajor = dataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR];
- outPointerCoords.touchMinor = dataSamples[sampleIndex + SAMPLE_TOUCH_MINOR];
- outPointerCoords.toolMajor = dataSamples[sampleIndex + SAMPLE_TOOL_MAJOR];
- outPointerCoords.toolMinor = dataSamples[sampleIndex + SAMPLE_TOOL_MINOR];
- outPointerCoords.orientation = dataSamples[sampleIndex + SAMPLE_ORIENTATION];
- }
-
- private final void setPointerCoordsAtSampleIndex(int sampleIndex,
- PointerCoords[] pointerCoords) {
- final int numPointers = mNumPointers;
- for (int i = 0; i < numPointers; i++) {
- setPointerCoordsAtSampleIndex(sampleIndex, pointerCoords[i]);
- sampleIndex += NUM_SAMPLE_DATA;
- }
- }
-
- private final void setPointerCoordsAtSampleIndex(int sampleIndex,
- PointerCoords pointerCoords) {
- final float[] dataSamples = mDataSamples;
- dataSamples[sampleIndex + SAMPLE_X] = pointerCoords.x - mXOffset;
- dataSamples[sampleIndex + SAMPLE_Y] = pointerCoords.y - mYOffset;
- dataSamples[sampleIndex + SAMPLE_PRESSURE] = pointerCoords.pressure;
- dataSamples[sampleIndex + SAMPLE_SIZE] = pointerCoords.size;
- dataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR] = pointerCoords.touchMajor;
- dataSamples[sampleIndex + SAMPLE_TOUCH_MINOR] = pointerCoords.touchMinor;
- dataSamples[sampleIndex + SAMPLE_TOOL_MAJOR] = pointerCoords.toolMajor;
- dataSamples[sampleIndex + SAMPLE_TOOL_MINOR] = pointerCoords.toolMinor;
- dataSamples[sampleIndex + SAMPLE_ORIENTATION] = pointerCoords.orientation;
- }
-
- private final void setPointerCoordsAtSampleIndex(int sampleIndex,
- float x, float y, float pressure, float size) {
- final float[] dataSamples = mDataSamples;
- dataSamples[sampleIndex + SAMPLE_X] = x - mXOffset;
- dataSamples[sampleIndex + SAMPLE_Y] = y - mYOffset;
- dataSamples[sampleIndex + SAMPLE_PRESSURE] = pressure;
- dataSamples[sampleIndex + SAMPLE_SIZE] = size;
- dataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR] = pressure;
- dataSamples[sampleIndex + SAMPLE_TOUCH_MINOR] = pressure;
- dataSamples[sampleIndex + SAMPLE_TOOL_MAJOR] = size;
- dataSamples[sampleIndex + SAMPLE_TOOL_MINOR] = size;
- dataSamples[sampleIndex + SAMPLE_ORIENTATION] = 0;
- }
-
- private final void incrementNumSamplesAndReserveStorage(int dataSampleStride) {
- if (mNumSamples == mEventTimeNanoSamples.length) {
- long[] newEventTimeNanoSamples = new long[mNumSamples + BASE_AVAIL_SAMPLES];
- System.arraycopy(mEventTimeNanoSamples, 0, newEventTimeNanoSamples, 0, mNumSamples);
- mEventTimeNanoSamples = newEventTimeNanoSamples;
- }
-
- int nextDataSampleIndex = mLastDataSampleIndex + dataSampleStride;
- if (nextDataSampleIndex + dataSampleStride > mDataSamples.length) {
- float[] newDataSamples = new float[nextDataSampleIndex
- + BASE_AVAIL_SAMPLES * dataSampleStride];
- System.arraycopy(mDataSamples, 0, newDataSamples, 0, nextDataSampleIndex);
- mDataSamples = newDataSamples;
- }
-
- mLastEventTimeNanoSampleIndex = mNumSamples;
- mLastDataSampleIndex = nextDataSampleIndex;
- mNumSamples += 1;
+ nativeTransform(mNativePtr, matrix);
}
/**
* Add a new movement to the batch of movements in this event. The event's
* current location, position and size is updated to the new values.
* The current values in the event are added to a list of historical values.
- *
- * Only applies to {@link #ACTION_MOVE} events.
+ *
+ * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events.
*
* @param eventTime The time stamp (in ms) for this data.
* @param x The new X position.
@@ -1526,40 +2105,37 @@
*/
public final void addBatch(long eventTime, float x, float y,
float pressure, float size, int metaState) {
- incrementNumSamplesAndReserveStorage(NUM_SAMPLE_DATA);
-
- mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
- setPointerCoordsAtSampleIndex(mLastDataSampleIndex, x, y, pressure, size);
-
- mMetaState |= metaState;
+ synchronized (gTmpPointerCoords) {
+ final PointerCoords pc = gTmpPointerCoords[0];
+ pc.clear();
+ pc.x = x;
+ pc.y = y;
+ pc.pressure = pressure;
+ pc.size = size;
+ nativeAddBatch(mNativePtr, eventTime * NS_PER_MS, gTmpPointerCoords, metaState);
+ }
}
/**
* Add a new movement to the batch of movements in this event. The event's
* current location, position and size is updated to the new values.
* The current values in the event are added to a list of historical values.
- *
- * Only applies to {@link #ACTION_MOVE} events.
+ *
+ * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events.
*
* @param eventTime The time stamp (in ms) for this data.
* @param pointerCoords The new pointer coordinates.
* @param metaState Meta key state.
*/
public final void addBatch(long eventTime, PointerCoords[] pointerCoords, int metaState) {
- final int dataSampleStride = mNumPointers * NUM_SAMPLE_DATA;
- incrementNumSamplesAndReserveStorage(dataSampleStride);
-
- mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
- setPointerCoordsAtSampleIndex(mLastDataSampleIndex, pointerCoords);
-
- mMetaState |= metaState;
+ nativeAddBatch(mNativePtr, eventTime * NS_PER_MS, pointerCoords, metaState);
}
@Override
public String toString() {
return "MotionEvent{" + Integer.toHexString(System.identityHashCode(this))
+ " pointerId=" + getPointerId(0)
- + " action=" + actionToString(mAction)
+ + " action=" + actionToString(getAction())
+ " x=" + getX()
+ " y=" + getY()
+ " pressure=" + getPressure()
@@ -1569,13 +2145,13 @@
+ " toolMajor=" + getToolMajor()
+ " toolMinor=" + getToolMinor()
+ " orientation=" + getOrientation()
- + " meta=" + KeyEvent.metaStateToString(mMetaState)
+ + " meta=" + KeyEvent.metaStateToString(getMetaState())
+ " pointerCount=" + getPointerCount()
+ " historySize=" + getHistorySize()
- + " flags=0x" + Integer.toHexString(mFlags)
- + " edgeFlags=0x" + Integer.toHexString(mEdgeFlags)
- + " device=" + mDeviceId
- + " source=0x" + Integer.toHexString(mSource)
+ + " flags=0x" + Integer.toHexString(getFlags())
+ + " edgeFlags=0x" + Integer.toHexString(getEdgeFlags())
+ + " device=" + getDeviceId()
+ + " source=0x" + Integer.toHexString(getSource())
+ (getPointerCount() > 1 ?
" pointerId2=" + getPointerId(1) + " x2=" + getX(1) + " y2=" + getY(1) : "")
+ "}";
@@ -1583,7 +2159,8 @@
/**
* Returns a string that represents the symbolic name of the specified action
- * such as "ACTION_DOWN", "ACTION_POINTER_DOWN(3)" or "35" (if unknown).
+ * such as "ACTION_DOWN", "ACTION_POINTER_DOWN(3)" or an equivalent numeric constant
+ * such as "35" if unknown.
*
* @param action The action.
* @return The symbolic name of the specified action.
@@ -1599,6 +2176,8 @@
return "ACTION_CANCEL";
case ACTION_MOVE:
return "ACTION_MOVE";
+ case ACTION_HOVER_MOVE:
+ return "ACTION_HOVER_MOVE";
}
int index = (action & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
switch (action & ACTION_MASK) {
@@ -1611,6 +2190,45 @@
}
}
+ /**
+ * Returns a string that represents the symbolic name of the specified axis
+ * such as "AXIS_X" or an equivalent numeric constant such as "42" if unknown.
+ *
+ * @param axis The axis
+ * @return The symbolic name of the specified axis.
+ */
+ public static String axisToString(int axis) {
+ String symbolicName = AXIS_SYMBOLIC_NAMES.get(axis);
+ return symbolicName != null ? symbolicName : Integer.toString(axis);
+ }
+
+ /**
+ * Gets an axis by its symbolic name such as "AXIS_X" or an
+ * equivalent numeric constant such as "42".
+ *
+ * @param symbolicName The symbolic name of the axis.
+ * @return The axis or -1 if not found.
+ * @see #keycodeToString
+ */
+ public static int axisFromString(String symbolicName) {
+ if (symbolicName == null) {
+ throw new IllegalArgumentException("symbolicName must not be null");
+ }
+
+ final int count = AXIS_SYMBOLIC_NAMES.size();
+ for (int i = 0; i < count; i++) {
+ if (symbolicName.equals(AXIS_SYMBOLIC_NAMES.valueAt(i))) {
+ return i;
+ }
+ }
+
+ try {
+ return Integer.parseInt(symbolicName, 10);
+ } catch (NumberFormatException ex) {
+ return -1;
+ }
+ }
+
public static final Parcelable.Creator<MotionEvent> CREATOR
= new Parcelable.Creator<MotionEvent>() {
public MotionEvent createFromParcel(Parcel in) {
@@ -1625,84 +2243,16 @@
/** @hide */
public static MotionEvent createFromParcelBody(Parcel in) {
- final int NP = in.readInt();
- final int NS = in.readInt();
- final int NI = NP * NS * NUM_SAMPLE_DATA;
-
- MotionEvent ev = obtain(NP, NS);
- ev.mNumPointers = NP;
- ev.mNumSamples = NS;
-
- ev.readBaseFromParcel(in);
-
- ev.mDownTimeNano = in.readLong();
- ev.mAction = in.readInt();
- ev.mXOffset = in.readFloat();
- ev.mYOffset = in.readFloat();
- ev.mXPrecision = in.readFloat();
- ev.mYPrecision = in.readFloat();
- ev.mEdgeFlags = in.readInt();
- ev.mMetaState = in.readInt();
- ev.mFlags = in.readInt();
-
- final int[] pointerIdentifiers = ev.mPointerIdentifiers;
- for (int i = 0; i < NP; i++) {
- pointerIdentifiers[i] = in.readInt();
- }
-
- final long[] eventTimeNanoSamples = ev.mEventTimeNanoSamples;
- for (int i = 0; i < NS; i++) {
- eventTimeNanoSamples[i] = in.readLong();
- }
-
- final float[] dataSamples = ev.mDataSamples;
- for (int i = 0; i < NI; i++) {
- dataSamples[i] = in.readFloat();
- }
-
- ev.mLastEventTimeNanoSampleIndex = NS - 1;
- ev.mLastDataSampleIndex = (NS - 1) * NP * NUM_SAMPLE_DATA;
+ MotionEvent ev = obtain();
+ ev.mNativePtr = nativeReadFromParcel(ev.mNativePtr, in);
return ev;
}
-
+
public void writeToParcel(Parcel out, int flags) {
out.writeInt(PARCEL_TOKEN_MOTION_EVENT);
-
- final int NP = mNumPointers;
- final int NS = mNumSamples;
- final int NI = NP * NS * NUM_SAMPLE_DATA;
-
- out.writeInt(NP);
- out.writeInt(NS);
-
- writeBaseToParcel(out);
-
- out.writeLong(mDownTimeNano);
- out.writeInt(mAction);
- out.writeFloat(mXOffset);
- out.writeFloat(mYOffset);
- out.writeFloat(mXPrecision);
- out.writeFloat(mYPrecision);
- out.writeInt(mEdgeFlags);
- out.writeInt(mMetaState);
- out.writeInt(mFlags);
-
- final int[] pointerIdentifiers = mPointerIdentifiers;
- for (int i = 0; i < NP; i++) {
- out.writeInt(pointerIdentifiers[i]);
- }
-
- final long[] eventTimeNanoSamples = mEventTimeNanoSamples;
- for (int i = 0; i < NS; i++) {
- out.writeLong(eventTimeNanoSamples[i]);
- }
-
- final float[] dataSamples = mDataSamples;
- for (int i = 0; i < NI; i++) {
- out.writeFloat(dataSamples[i]);
- }
+ nativeWriteToParcel(mNativePtr, out);
}
-
+
/**
* Transfer object for pointer coordinates.
*
@@ -1713,49 +2263,81 @@
* input devices and sources represent pointer coordinates.
*/
public static final class PointerCoords {
+ private static final int INITIAL_PACKED_AXIS_VALUES = 8;
+ private long mPackedAxisBits;
+ private float[] mPackedAxisValues;
+
/**
- * The X coordinate of the pointer movement.
- * The interpretation varies by input source and may represent the position of
- * the center of the contact area, a relative displacement in device-specific units
- * or something else.
+ * Creates a pointer coords object with all axes initialized to zero.
+ */
+ public PointerCoords() {
+ }
+
+ /**
+ * Creates a pointer coords object as a copy of the
+ * contents of another pointer coords object.
+ *
+ * @param other The pointer coords object to copy.
+ */
+ public PointerCoords(PointerCoords other) {
+ copyFrom(other);
+ }
+
+ /**
+ * The X component of the pointer movement.
+ *
+ * @see MotionEvent#AXIS_X
*/
public float x;
/**
- * The Y coordinate of the pointer movement.
- * The interpretation varies by input source and may represent the position of
- * the center of the contact area, a relative displacement in device-specific units
- * or something else.
+ * The Y component of the pointer movement.
+ *
+ * @see MotionEvent#AXIS_Y
*/
public float y;
/**
- * A scaled value that describes the pressure applied to the pointer.
+ * A normalized value that describes the pressure applied to the device
+ * by a finger or other tool.
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
+ * although values higher than 1 may be generated depending on the calibration of
* the input device.
+ *
+ * @see MotionEvent#AXIS_PRESSURE
*/
public float pressure;
/**
- * A scaled value of the approximate size of the pointer touch area.
- * This represents some approximation of the area of the screen being
+ * A normalized value that describes the approximate size of the pointer touch area
+ * in relation to the maximum detectable size of the device.
+ * It represents some approximation of the area of the screen being
* pressed; the actual value in pixels corresponding to the
* touch is normalized with the device specific range of values
* and scaled to a value between 0 and 1. The value of size can be used to
* determine fat touch events.
+ *
+ * @see MotionEvent#AXIS_SIZE
*/
public float size;
/**
* The length of the major axis of an ellipse that describes the touch area at
* the point of contact.
+ * If the device is a touch screen, the length is reported in pixels, otherwise it is
+ * reported in device-specific units.
+ *
+ * @see MotionEvent#AXIS_TOUCH_MAJOR
*/
public float touchMajor;
/**
* The length of the minor axis of an ellipse that describes the touch area at
* the point of contact.
+ * If the device is a touch screen, the length is reported in pixels, otherwise it is
+ * reported in device-specific units.
+ *
+ * @see MotionEvent#AXIS_TOUCH_MINOR
*/
public float touchMinor;
@@ -1764,6 +2346,10 @@
* the approaching tool.
* The tool area represents the estimated size of the finger or pen that is
* touching the device independent of its actual touch area at the point of contact.
+ * If the device is a touch screen, the length is reported in pixels, otherwise it is
+ * reported in device-specific units.
+ *
+ * @see MotionEvent#AXIS_TOOL_MAJOR
*/
public float toolMajor;
@@ -1772,38 +2358,189 @@
* the approaching tool.
* The tool area represents the estimated size of the finger or pen that is
* touching the device independent of its actual touch area at the point of contact.
+ * If the device is a touch screen, the length is reported in pixels, otherwise it is
+ * reported in device-specific units.
+ *
+ * @see MotionEvent#AXIS_TOOL_MINOR
*/
public float toolMinor;
/**
* The orientation of the touch area and tool area in radians clockwise from vertical.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * An angle of 0 radians indicates that the major axis of contact is oriented
* upwards, is perfectly circular or is of unknown orientation. A positive angle
* indicates that the major axis of contact is oriented to the right. A negative angle
* indicates that the major axis of contact is oriented to the left.
* The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
* (finger pointing fully right).
+ *
+ * @see MotionEvent#AXIS_ORIENTATION
*/
public float orientation;
-
- /*
- private static final float PI_4 = (float) (Math.PI / 4);
-
- public float getTouchWidth() {
- return Math.abs(orientation) > PI_4 ? touchMajor : touchMinor;
+
+ /**
+ * Clears the contents of this object.
+ * Resets all axes to zero.
+ */
+ public void clear() {
+ mPackedAxisBits = 0;
+
+ x = 0;
+ y = 0;
+ pressure = 0;
+ size = 0;
+ touchMajor = 0;
+ touchMinor = 0;
+ toolMajor = 0;
+ toolMinor = 0;
+ orientation = 0;
}
-
- public float getTouchHeight() {
- return Math.abs(orientation) > PI_4 ? touchMinor : touchMajor;
+
+ /**
+ * Copies the contents of another pointer coords object.
+ *
+ * @param other The pointer coords object to copy.
+ */
+ public void copyFrom(PointerCoords other) {
+ final long bits = other.mPackedAxisBits;
+ mPackedAxisBits = bits;
+ if (bits != 0) {
+ final float[] otherValues = other.mPackedAxisValues;
+ final int count = Long.bitCount(bits);
+ float[] values = mPackedAxisValues;
+ if (values == null || count > values.length) {
+ values = new float[otherValues.length];
+ mPackedAxisValues = values;
+ }
+ System.arraycopy(otherValues, 0, values, 0, count);
+ }
+
+ x = other.x;
+ y = other.y;
+ pressure = other.pressure;
+ size = other.size;
+ touchMajor = other.touchMajor;
+ touchMinor = other.touchMinor;
+ toolMajor = other.toolMajor;
+ toolMinor = other.toolMinor;
+ orientation = other.orientation;
}
-
- public float getToolWidth() {
- return Math.abs(orientation) > PI_4 ? toolMajor : toolMinor;
+
+ /**
+ * Gets the value associated with the specified axis.
+ *
+ * @param axis The axis identifier for the axis value to retrieve.
+ * @return The value associated with the axis, or 0 if none.
+ *
+ * @see MotionEvent#AXIS_X
+ * @see MotionEvent#AXIS_Y
+ */
+ public float getAxisValue(int axis) {
+ switch (axis) {
+ case AXIS_X:
+ return x;
+ case AXIS_Y:
+ return y;
+ case AXIS_PRESSURE:
+ return pressure;
+ case AXIS_SIZE:
+ return size;
+ case AXIS_TOUCH_MAJOR:
+ return touchMajor;
+ case AXIS_TOUCH_MINOR:
+ return touchMinor;
+ case AXIS_TOOL_MAJOR:
+ return toolMajor;
+ case AXIS_TOOL_MINOR:
+ return toolMinor;
+ case AXIS_ORIENTATION:
+ return orientation;
+ default: {
+ if (axis < 0 || axis > 63) {
+ throw new IllegalArgumentException("Axis out of range.");
+ }
+ final long bits = mPackedAxisBits;
+ final long axisBit = 1L << axis;
+ if ((bits & axisBit) == 0) {
+ return 0;
+ }
+ final int index = Long.bitCount(bits & (axisBit - 1L));
+ return mPackedAxisValues[index];
+ }
+ }
}
-
- public float getToolHeight() {
- return Math.abs(orientation) > PI_4 ? toolMinor : toolMajor;
+
+ /**
+ * Sets the value associated with the specified axis.
+ *
+ * @param axis The axis identifier for the axis value to assign.
+ * @param value The value to set.
+ *
+ * @see MotionEvent#AXIS_X
+ * @see MotionEvent#AXIS_Y
+ */
+ public void setAxisValue(int axis, float value) {
+ switch (axis) {
+ case AXIS_X:
+ x = value;
+ break;
+ case AXIS_Y:
+ y = value;
+ break;
+ case AXIS_PRESSURE:
+ pressure = value;
+ break;
+ case AXIS_SIZE:
+ size = value;
+ break;
+ case AXIS_TOUCH_MAJOR:
+ touchMajor = value;
+ break;
+ case AXIS_TOUCH_MINOR:
+ touchMinor = value;
+ break;
+ case AXIS_TOOL_MAJOR:
+ toolMajor = value;
+ break;
+ case AXIS_TOOL_MINOR:
+ toolMinor = value;
+ break;
+ case AXIS_ORIENTATION:
+ orientation = value;
+ break;
+ default: {
+ if (axis < 0 || axis > 63) {
+ throw new IllegalArgumentException("Axis out of range.");
+ }
+ final long bits = mPackedAxisBits;
+ final long axisBit = 1L << axis;
+ final int index = Long.bitCount(bits & (axisBit - 1L));
+ float[] values = mPackedAxisValues;
+ if ((bits & axisBit) == 0) {
+ if (values == null) {
+ values = new float[INITIAL_PACKED_AXIS_VALUES];
+ mPackedAxisValues = values;
+ } else {
+ final int count = Long.bitCount(bits);
+ if (count < values.length) {
+ if (index != count) {
+ System.arraycopy(values, index, values, index + 1,
+ count - index);
+ }
+ } else {
+ float[] newValues = new float[count * 2];
+ System.arraycopy(values, 0, newValues, 0, index);
+ System.arraycopy(values, index, newValues, index + 1,
+ count - index);
+ values = newValues;
+ mPackedAxisValues = values;
+ }
+ }
+ mPackedAxisBits = bits | axisBit;
+ }
+ values[index] = value;
+ }
+ }
}
- */
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b982c7b..eefce06 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -74,6 +74,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.WeakHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -2099,6 +2100,11 @@
private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
/**
+ * Listeners for attach events.
+ */
+ private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
+
+ /**
* Listener used to dispatch click events.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
@@ -2996,6 +3002,37 @@
}
/**
+ * Add a listener for attach state changes.
+ *
+ * This listener will be called whenever this view is attached or detached
+ * from a window. Remove the listener using
+ * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
+ *
+ * @param listener Listener to attach
+ * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
+ */
+ public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
+ if (mOnAttachStateChangeListeners == null) {
+ mOnAttachStateChangeListeners = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
+ }
+ mOnAttachStateChangeListeners.add(listener);
+ }
+
+ /**
+ * Remove a listener for attach state changes. The listener will receive no further
+ * notification of window attach/detach events.
+ *
+ * @param listener Listener to remove
+ * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
+ */
+ public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
+ if (mOnAttachStateChangeListeners == null) {
+ return;
+ }
+ mOnAttachStateChangeListeners.remove(listener);
+ }
+
+ /**
* Returns the focus-change callback registered for this view.
*
* @return The callback, or null if one is not registered.
@@ -6061,9 +6098,7 @@
if (top != mTop) {
updateMatrix();
if (mMatrixIsIdentity) {
- final ViewParent p = mParent;
- if (p != null && mAttachInfo != null) {
- final Rect r = mAttachInfo.mTmpInvalRect;
+ if (mAttachInfo != null) {
int minTop;
int yLoc;
if (top < mTop) {
@@ -6073,8 +6108,7 @@
minTop = mTop;
yLoc = 0;
}
- r.set(0, yLoc, mRight - mLeft, mBottom - minTop);
- p.invalidateChild(this, r);
+ invalidate(0, yLoc, mRight - mLeft, mBottom - minTop);
}
} else {
// Double-invalidation is necessary to capture view's old and new areas
@@ -6131,17 +6165,14 @@
if (bottom != mBottom) {
updateMatrix();
if (mMatrixIsIdentity) {
- final ViewParent p = mParent;
- if (p != null && mAttachInfo != null) {
- final Rect r = mAttachInfo.mTmpInvalRect;
+ if (mAttachInfo != null) {
int maxBottom;
if (bottom < mBottom) {
maxBottom = mBottom;
} else {
maxBottom = bottom;
}
- r.set(0, 0, mRight - mLeft, maxBottom - mTop);
- p.invalidateChild(this, r);
+ invalidate(0, 0, mRight - mLeft, maxBottom - mTop);
}
} else {
// Double-invalidation is necessary to capture view's old and new areas
@@ -6189,9 +6220,7 @@
if (left != mLeft) {
updateMatrix();
if (mMatrixIsIdentity) {
- final ViewParent p = mParent;
- if (p != null && mAttachInfo != null) {
- final Rect r = mAttachInfo.mTmpInvalRect;
+ if (mAttachInfo != null) {
int minLeft;
int xLoc;
if (left < mLeft) {
@@ -6201,8 +6230,7 @@
minLeft = mLeft;
xLoc = 0;
}
- r.set(xLoc, 0, mRight - minLeft, mBottom - mTop);
- p.invalidateChild(this, r);
+ invalidate(xLoc, 0, mRight - minLeft, mBottom - mTop);
}
} else {
// Double-invalidation is necessary to capture view's old and new areas
@@ -6250,17 +6278,14 @@
if (right != mRight) {
updateMatrix();
if (mMatrixIsIdentity) {
- final ViewParent p = mParent;
- if (p != null && mAttachInfo != null) {
- final Rect r = mAttachInfo.mTmpInvalRect;
+ if (mAttachInfo != null) {
int maxRight;
if (right < mRight) {
maxRight = mRight;
} else {
maxRight = right;
}
- r.set(0, 0, maxRight - mLeft, mBottom - mTop);
- p.invalidateChild(this, r);
+ invalidate(0, 0, maxRight - mLeft, mBottom - mTop);
}
} else {
// Double-invalidation is necessary to capture view's old and new areas
@@ -7965,6 +7990,19 @@
}
performCollectViewAttributes(visibility);
onAttachedToWindow();
+
+ final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
+ mOnAttachStateChangeListeners;
+ if (listeners != null && listeners.size() > 0) {
+ // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+ // perform the dispatching. The iterator is a safe guard against listeners that
+ // could mutate the list by calling the various add/remove methods. This prevents
+ // the array from being modified while we iterate it.
+ for (OnAttachStateChangeListener listener : listeners) {
+ listener.onViewAttachedToWindow(this);
+ }
+ }
+
int vis = info.mWindowVisibility;
if (vis != GONE) {
onWindowVisibilityChanged(vis);
@@ -7986,6 +8024,18 @@
onDetachedFromWindow();
+ final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
+ mOnAttachStateChangeListeners;
+ if (listeners != null && listeners.size() > 0) {
+ // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+ // perform the dispatching. The iterator is a safe guard against listeners that
+ // could mutate the list by calling the various add/remove methods. This prevents
+ // the array from being modified while we iterate it.
+ for (OnAttachStateChangeListener listener : listeners) {
+ listener.onViewDetachedFromWindow(this);
+ }
+ }
+
if ((mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0) {
mAttachInfo.mScrollContainers.remove(this);
mPrivateFlags &= ~SCROLL_CONTAINER_ADDED;
@@ -11779,6 +11829,23 @@
public void onSystemUiVisibilityChange(int visibility);
}
+ /**
+ * Interface definition for a callback to be invoked when this view is attached
+ * or detached from its window.
+ */
+ public interface OnAttachStateChangeListener {
+ /**
+ * Called when the view is attached to a window.
+ * @param v The view that was attached
+ */
+ public void onViewAttachedToWindow(View v);
+ /**
+ * Called when the view is detached from a window.
+ * @param v The view that was detached
+ */
+ public void onViewDetachedFromWindow(View v);
+ }
+
private final class UnsetPressedState implements Runnable {
public void run() {
setPressed(false);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b5a2558..a0d4263 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1166,7 +1166,8 @@
final int actionMasked = action & MotionEvent.ACTION_MASK;
// Handle an initial down.
- if (actionMasked == MotionEvent.ACTION_DOWN) {
+ if (actionMasked == MotionEvent.ACTION_DOWN
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
@@ -1176,7 +1177,9 @@
// Check for interception.
final boolean intercepted;
- if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
+ if (actionMasked == MotionEvent.ACTION_DOWN
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE
+ || mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
@@ -1198,7 +1201,8 @@
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
if (actionMasked == MotionEvent.ACTION_DOWN
- || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)) {
+ || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
final int actionIndex = ev.getActionIndex(); // always 0 for down
final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
: TouchTarget.ALL_POINTER_IDS;
@@ -1299,7 +1303,9 @@
}
// Update list of touch targets for pointer up or cancel, if needed.
- if (canceled || actionMasked == MotionEvent.ACTION_UP) {
+ if (canceled
+ || actionMasked == MotionEvent.ACTION_UP
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
resetTouchState();
} else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
final int actionIndex = ev.getActionIndex();
@@ -1542,6 +1548,8 @@
final int newAction;
if (cancel) {
newAction = MotionEvent.ACTION_CANCEL;
+ } else if (oldAction == MotionEvent.ACTION_HOVER_MOVE) {
+ newAction = MotionEvent.ACTION_HOVER_MOVE;
} else {
final int oldMaskedAction = oldAction & MotionEvent.ACTION_MASK;
if (oldMaskedAction == MotionEvent.ACTION_POINTER_DOWN
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ec1a373..39f99b8 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2496,7 +2496,6 @@
// Deliver the event to the view.
if (mView.dispatchGenericMotionEvent(event)) {
- ensureTouchMode(false);
if (isJoystick) {
updateJoystickDirection(event, false);
}
@@ -2525,8 +2524,16 @@
final int metaState = event.getMetaState();
final int deviceId = event.getDeviceId();
final int source = event.getSource();
- final int xDirection = joystickAxisValueToDirection(event.getX());
- final int yDirection = joystickAxisValueToDirection(event.getY());
+
+ int xDirection = joystickAxisValueToDirection(event.getAxisValue(MotionEvent.AXIS_HAT_X));
+ if (xDirection == 0) {
+ xDirection = joystickAxisValueToDirection(event.getX());
+ }
+
+ int yDirection = joystickAxisValueToDirection(event.getAxisValue(MotionEvent.AXIS_HAT_Y));
+ if (yDirection == 0) {
+ yDirection = joystickAxisValueToDirection(event.getY());
+ }
if (xDirection != mLastJoystickXDirection) {
if (mLastJoystickXKeyCode != 0) {
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 89b7aaa..9e9f46f 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -129,6 +129,7 @@
// List of stream types and their order
// RING and VOICE_CALL are hidden unless explicitly requested
private static final int [] STREAM_TYPES = {
+ AudioManager.STREAM_BLUETOOTH_SCO,
AudioManager.STREAM_RING,
AudioManager.STREAM_VOICE_CALL,
AudioManager.STREAM_MUSIC,
@@ -137,6 +138,7 @@
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_NORMAL = {
+ R.drawable.ic_audio_bt,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol,
@@ -145,6 +147,7 @@
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_MUTED = {
+ R.drawable.ic_audio_bt,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol_mute,
@@ -277,6 +280,7 @@
final int streamType = STREAM_TYPES[i];
if (streamType == AudioManager.STREAM_RING
|| streamType == AudioManager.STREAM_VOICE_CALL
+ || streamType == AudioManager.STREAM_BLUETOOTH_SCO
|| streamType == activeStreamType) {
continue;
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8e09986..fc1240f 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -21,6 +21,8 @@
import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.net.ParseException;
import android.net.Uri;
@@ -933,7 +935,19 @@
if (androidResource != null) {
return new WebResourceResponse(null, null, androidResource);
}
- return mCallbackProxy.shouldInterceptRequest(url);
+ WebResourceResponse response = mCallbackProxy.shouldInterceptRequest(url);
+ if (response == null && "browser:incognito".equals(url)) {
+ try {
+ Resources res = mContext.getResources();
+ InputStream ins = res.openRawResource(
+ com.android.internal.R.raw.incognito_mode_start_page);
+ response = new WebResourceResponse("text/html", "utf8", ins);
+ } catch (NotFoundException ex) {
+ // This shouldn't happen, but try and gracefully handle it jic
+ Log.w(LOGTAG, "Failed opening raw.incognito_mode_start_page", ex);
+ }
+ }
+ return response;
}
/**
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 04062fe..3ce0730 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -198,8 +198,6 @@
mBaseDir = new File(context.getCacheDir(), "webviewCacheChromiumStaging");
if (!mBaseDir.exists()) {
mBaseDir.mkdirs();
- } else {
- // TODO: Should we clear out old files?
}
return;
}
@@ -605,11 +603,12 @@
* @return Whether the removal succeeded.
*/
static boolean removeAllCacheFiles() {
- assert !JniUtil.useChromiumHttpStack();
-
// Note, this is called before init() when the database is
// created or upgraded.
if (mBaseDir == null) {
+ // This method should not be called before init() when using the
+ // chrome http stack
+ assert !JniUtil.useChromiumHttpStack();
// Init() has not been called yet, so just flag that
// we need to clear the cache when init() is called.
mClearCacheOnInit = true;
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 8393980..313f755 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -178,14 +178,16 @@
return;
}
- manager.flushCookieStore();
+ if (JniUtil.useChromiumHttpStack()) {
+ manager.flushCookieStore();
+ } else {
+ ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
+ mLastUpdate = System.currentTimeMillis();
+ syncFromRamToFlash(cookieList);
- ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
- mLastUpdate = System.currentTimeMillis();
- syncFromRamToFlash(cookieList);
-
- ArrayList<Cookie> lruList = manager.deleteLRUDomain();
- syncFromRamToFlash(lruList);
+ ArrayList<Cookie> lruList = manager.deleteLRUDomain();
+ syncFromRamToFlash(lruList);
+ }
if (DebugFlags.COOKIE_SYNC_MANAGER) {
Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 3cb5e24..2dac7e9 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -31,7 +31,7 @@
public static final boolean CACHE_MANAGER = false;
public static final boolean CALLBACK_PROXY = false;
public static final boolean COOKIE_MANAGER = false;
- public static final boolean COOKIE_SYNC_MANAGER = false;
+ public static final boolean COOKIE_SYNC_MANAGER = true;
public static final boolean FRAME_LOADER = false;
public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
public static final boolean LOAD_LISTENER = false;
@@ -41,7 +41,7 @@
public static final boolean URL_UTIL = false;
public static final boolean WEB_BACK_FORWARD_LIST = false;
public static final boolean WEB_SETTINGS = false;
- public static final boolean WEB_SYNC_MANAGER = false;
+ public static final boolean WEB_SYNC_MANAGER = true;
public static final boolean WEB_TEXT_VIEW = false;
public static final boolean WEB_VIEW = false;
public static final boolean WEB_VIEW_CORE = false;
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index d8f34e0..3caf345 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -46,6 +46,8 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
@@ -344,7 +346,7 @@
private static RequestQueue mRequestQueue;
private static int mQueueRefCount = 0;
// The poster URL
- private String mUrl;
+ private URL mUrl;
// The proxy we're doing this for.
private final HTML5VideoViewProxy mProxy;
// The poster bytes. We only touch this on the network thread.
@@ -359,14 +361,30 @@
private Handler mHandler;
public PosterDownloader(String url, HTML5VideoViewProxy proxy) {
- mUrl = url;
+ try {
+ mUrl = new URL(url);
+ } catch (MalformedURLException e) {
+ mUrl = null;
+ }
mProxy = proxy;
mHandler = new Handler();
}
// Start the download. Called on WebCore thread.
public void start() {
retainQueue();
- mRequestHandle = mRequestQueue.queueRequest(mUrl, "GET", null, this, null, 0);
+
+ if (mUrl == null) {
+ return;
+ }
+
+ // Only support downloading posters over http/https.
+ // FIXME: Add support for other schemes. WebKit seems able to load
+ // posters over other schemes e.g. file://, but gets the dimensions wrong.
+ String protocol = mUrl.getProtocol();
+ if ("http".equals(protocol) || "https".equals(protocol)) {
+ mRequestHandle = mRequestQueue.queueRequest(mUrl.toString(), "GET", null,
+ this, null, 0);
+ }
}
// Cancel the download if active and release the queue. Called on WebCore thread.
public void cancelAndReleaseQueue() {
@@ -405,12 +423,16 @@
cleanup();
} else if (mStatusCode >= 300 && mStatusCode < 400) {
// We have a redirect.
- mUrl = mHeaders.getLocation();
+ try {
+ mUrl = new URL(mHeaders.getLocation());
+ } catch (MalformedURLException e) {
+ mUrl = null;
+ }
if (mUrl != null) {
mHandler.post(new Runnable() {
public void run() {
if (mRequestHandle != null) {
- mRequestHandle.setupRedirect(mUrl, mStatusCode,
+ mRequestHandle.setupRedirect(mUrl.toString(), mStatusCode,
new HashMap<String, String>());
}
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 0bf0eab..71d6080 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -174,6 +174,7 @@
private boolean mBlockNetworkImage = false;
private boolean mBlockNetworkLoads;
private boolean mJavaScriptEnabled = false;
+ private boolean mShowVisualIndicator = false;
private PluginState mPluginState = PluginState.OFF;
private boolean mJavaScriptCanOpenWindowsAutomatically = false;
private boolean mUseDoubleTree = false;
@@ -1191,6 +1192,26 @@
}
/**
+ * Tell the WebView to show the visual indicator
+ * @param flag True if the WebView should show the visual indicator
+ * @hide
+ */
+ public synchronized void setShowVisualIndicator(boolean flag) {
+ if (mShowVisualIndicator != flag) {
+ mShowVisualIndicator = flag;
+ postSync();
+ }
+ }
+
+ /**
+ * @return True if the WebView is showing the visual indicator
+ * @hide
+ */
+ public synchronized boolean getShowVisualIndicator() {
+ return mShowVisualIndicator;
+ }
+
+ /**
* Tell the WebView to enable plugins.
* @param flag True if the WebView should load plugins.
* @deprecated This method has been deprecated in favor of
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7d8289a..d9f050b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -104,6 +104,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -811,7 +812,7 @@
private OverScrollGlow mOverScrollGlow;
// Used to match key downs and key ups
- private boolean mGotKeyDown;
+ private Vector<Integer> mKeysPressed;
/* package */ static boolean mLogEvent = true;
@@ -1177,6 +1178,9 @@
mOverflingDistance = configuration.getScaledOverflingDistance();
setScrollBarStyle(super.getScrollBarStyle());
+ // Initially use a size of two, since the user is likely to only hold
+ // down two keys at a time (shift + another key)
+ mKeysPressed = new Vector<Integer>(2);
}
/**
@@ -2089,7 +2093,7 @@
public void clearView() {
mContentWidth = 0;
mContentHeight = 0;
- setBaseLayer(0, null);
+ setBaseLayer(0, null, false);
mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
}
@@ -3302,7 +3306,7 @@
}
mPageThatNeedsToSlideTitleBarOffScreen = null;
}
-
+ mZoomManager.onPageFinished(url);
injectAccessibilityForUrl(url);
}
@@ -3996,14 +4000,14 @@
}
}
- void setBaseLayer(int layer, Rect invalRect) {
+ void setBaseLayer(int layer, Rect invalRect, boolean showVisualIndciator) {
if (mNativeClass == 0)
return;
if (invalRect == null) {
Rect rect = new Rect(0, 0, mContentWidth, mContentHeight);
- nativeSetBaseLayer(layer, rect);
+ nativeSetBaseLayer(layer, rect, showVisualIndciator);
} else {
- nativeSetBaseLayer(layer, invalRect);
+ nativeSetBaseLayer(layer, invalRect, showVisualIndciator);
}
}
@@ -5126,7 +5130,7 @@
*/
mDrawCursorRing = false;
}
- mGotKeyDown = false;
+ mKeysPressed.clear();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mTouchMode = TOUCH_DONE_MODE;
if (mNativeClass != 0) {
@@ -5196,7 +5200,7 @@
}
setFocusControllerActive(false);
}
- mGotKeyDown = false;
+ mKeysPressed.clear();
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
@@ -5271,39 +5275,36 @@
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- boolean dispatch = true;
-
- // Textfields, plugins, and contentEditable nodes need to receive the
- // shift up key even if another key was released while the shift key
- // was held down.
- boolean inEditingMode = inEditingMode();
- if (!inEditingMode && (mNativeClass == 0
- || !nativePageShouldHandleShiftAndArrows())) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- mGotKeyDown = true;
- } else {
- if (!mGotKeyDown && event.getAction() != KeyEvent.ACTION_MULTIPLE) {
- /*
- * We got a key up for which we were not the recipient of
- * the original key down. Don't give it to the view.
- */
- dispatch = false;
+ switch (event.getAction()) {
+ case KeyEvent.ACTION_DOWN:
+ mKeysPressed.add(Integer.valueOf(event.getKeyCode()));
+ break;
+ case KeyEvent.ACTION_MULTIPLE:
+ // Always accept the action.
+ break;
+ case KeyEvent.ACTION_UP:
+ int location = mKeysPressed.indexOf(Integer.valueOf(event.getKeyCode()));
+ if (location == -1) {
+ // We did not receive the key down for this key, so do not
+ // handle the key up.
+ return false;
+ } else {
+ // We did receive the key down. Handle the key up, and
+ // remove it from our pressed keys.
+ mKeysPressed.remove(location);
}
- mGotKeyDown = false;
- }
+ break;
+ default:
+ // Accept the action. This should not happen, unless a new
+ // action is added to KeyEvent.
+ break;
}
-
- if (dispatch) {
- if (inEditingMode) {
- // Ensure that the WebTextView gets the event, even if it does
- // not currently have a bounds.
- return mWebTextView.dispatchKeyEvent(event);
- } else {
- return super.dispatchKeyEvent(event);
- }
+ if (inEditingMode() && mWebTextView.isFocused()) {
+ // Ensure that the WebTextView gets the event, even if it does
+ // not currently have a bounds.
+ return mWebTextView.dispatchKeyEvent(event);
} else {
- // We didn't dispatch, so let something else handle the key
- return false;
+ return super.dispatchKeyEvent(event);
}
}
@@ -5507,8 +5508,8 @@
}
}
// Trigger the link
- if (mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
+ if (!mSelectingText && (mTouchMode == TOUCH_INIT_MODE
+ || mTouchMode == TOUCH_DOUBLE_TAP_MODE)) {
mPrivateHandler.sendEmptyMessageDelayed(
SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
mPrivateHandler.sendEmptyMessageDelayed(
@@ -5530,6 +5531,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
if (mDeferTouchProcess) {
// still needs to set them for compute deltaX/Y
@@ -5574,6 +5577,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
if (mDeferTouchProcess) {
@@ -5753,6 +5758,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5772,6 +5779,9 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
@@ -6003,6 +6013,8 @@
ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(x, y);
ted.mAction = MotionEvent.ACTION_CANCEL;
+ ted.mNativeLayer = nativeScrollableLayer(
+ x, y, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
@@ -6642,8 +6654,9 @@
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
- Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
- contentX + mNavSlop, contentY + mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ Rect rect = new Rect(contentX - slop, contentY - slop,
+ contentX + slop, contentY + slop);
nativeSelectBestAt(rect);
mInitialHitTestResult = hitTestResult(null);
}
@@ -6717,7 +6730,8 @@
}
int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
- nativeMotionUp(x, y, mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ nativeMotionUp(x, y, slop);
}
/**
@@ -6740,6 +6754,7 @@
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
+ int slop = viewToContentDimension(mNavSlop);
if (getSettings().supportTouchOnly()) {
removeTouchHighlight(false);
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -6747,7 +6762,7 @@
// it used when processing GET_TOUCH_HIGHLIGHT_RECTS
touchUpData.mMoveGeneration = 0;
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
- } else if (nativePointInNavCache(contentX, contentY, mNavSlop)) {
+ } else if (nativePointInNavCache(contentX, contentY, slop)) {
WebViewCore.MotionUpData motionUpData = new WebViewCore
.MotionUpData();
motionUpData.mFrame = nativeCacheHitFramePointer();
@@ -6763,7 +6778,8 @@
}
private void doMotionUp(int contentX, int contentY) {
- if (nativeMotionUp(contentX, contentY, mNavSlop) && mLogEvent) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativeMotionUp(contentX, contentY, slop) && mLogEvent) {
EventLog.writeEvent(EventLogTags.BROWSER_SNAP_CENTER);
}
if (nativeHasCursorNode() && !nativeCursorIsTextInput()) {
@@ -6776,7 +6792,8 @@
* plugin. Otherwise a NULL rectangle is returned.
*/
Rect getPluginBounds(int x, int y) {
- if (nativePointInNavCache(x, y, mNavSlop) && nativeCacheHitIsPlugin()) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativePointInNavCache(x, y, slop) && nativeCacheHitIsPlugin()) {
return nativeCacheHitNodeBounds();
} else {
return null;
@@ -7160,6 +7177,9 @@
// simplicity for now, we don't set it.
ted.mMetaState = 0;
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ ted.mPoints[0].x, ted.mPoints[0].y,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_DONE_MODE;
@@ -7205,7 +7225,8 @@
case NEW_PICTURE_MSG_ID: {
// called for new content
final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
- setBaseLayer(draw.mBaseLayer, draw.mInvalRegion.getBounds());
+ setBaseLayer(draw.mBaseLayer, draw.mInvalRegion.getBounds(),
+ getSettings().getShowVisualIndicator());
final Point viewSize = draw.mViewSize;
WebViewCore.ViewState viewState = draw.mViewState;
boolean isPictureAfterFirstLayout = viewState != null;
@@ -8031,6 +8052,8 @@
touchUpData.mNode = node;
touchUpData.mX = x;
touchUpData.mY = y;
+ touchUpData.mNativeLayer = nativeScrollableLayer(
+ x, y, touchUpData.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
}
@@ -8337,7 +8360,8 @@
private native void nativeSetFindIsEmpty();
private native void nativeSetFindIsUp(boolean isUp);
private native void nativeSetHeightCanMeasure(boolean measure);
- private native void nativeSetBaseLayer(int layer, Rect invalRect);
+ private native void nativeSetBaseLayer(int layer, Rect invalRect,
+ boolean showVisualIndciator);
private native void nativeShowCursorTimed();
private native void nativeReplaceBaseContent(int content);
private native void nativeCopyBaseContentToPicture(Picture pict);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 42889cb..fb0f61c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -778,6 +778,8 @@
int mNode;
int mX;
int mY;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class TouchHighlightData {
@@ -821,6 +823,8 @@
int mMetaState;
boolean mReprocess;
MotionEvent mMotionEvent;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class GeolocationPermissionsData {
@@ -1304,6 +1308,10 @@
case TOUCH_UP:
TouchUpData touchUpData = (TouchUpData) msg.obj;
+ if (touchUpData.mNativeLayer != 0) {
+ nativeScrollLayer(touchUpData.mNativeLayer,
+ touchUpData.mNativeLayerRect);
+ }
nativeTouchUp(touchUpData.mMoveGeneration,
touchUpData.mFrame, touchUpData.mNode,
touchUpData.mX, touchUpData.mY);
@@ -1318,6 +1326,10 @@
xArray[c] = ted.mPoints[c].x;
yArray[c] = ted.mPoints[c].y;
}
+ if (ted.mNativeLayer != 0) {
+ nativeScrollLayer(ted.mNativeLayer,
+ ted.mNativeLayerRect);
+ }
Message.obtain(
mWebView.mPrivateHandler,
WebView.PREVENT_TOUCH_ID,
@@ -1814,42 +1826,7 @@
Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
return;
}
- int width = w;
- if (mSettings.getUseWideViewPort()) {
- if (mViewportWidth == -1) {
- if (mSettings.getLayoutAlgorithm() ==
- WebSettings.LayoutAlgorithm.NORMAL || mSettings.getUseFixedViewport()) {
- width = WebView.DEFAULT_VIEWPORT_WIDTH;
- } else {
- /*
- * if a page's minimum preferred width is wider than the
- * given "w", use it instead to get better layout result. If
- * we start a page with MAX_ZOOM_WIDTH, "w" will be always
- * wider. If we start a page with screen width, due to the
- * delay between {@link #didFirstLayout} and
- * {@link #viewSizeChanged},
- * {@link #nativeGetContentMinPrefWidth} will return a more
- * accurate value than initial 0 to result a better layout.
- * In the worse case, the native width will be adjusted when
- * next zoom or screen orientation change happens.
- */
- width = Math.min(WebView.sMaxViewportWidth, Math.max(w,
- Math.max(WebView.DEFAULT_VIEWPORT_WIDTH,
- nativeGetContentMinPrefWidth())));
- }
- } else if (mViewportWidth > 0) {
- if (mSettings.getUseFixedViewport()) {
- // Use website specified or desired fixed viewport width.
- width = mViewportWidth;
- } else {
- width = Math.max(w, mViewportWidth);
- }
- } else if (mSettings.getUseFixedViewport()) {
- width = mWebView.getViewWidth();
- } else {
- width = textwrapWidth;
- }
- }
+ int width = calculateWindowWidth(w, textwrapWidth);
int height = h;
if (width != w) {
float heightWidthRatio = data.mHeightWidthRatio;
@@ -1874,6 +1851,47 @@
EventHub.UPDATE_CACHE_AND_TEXT_ENTRY));
}
+ // Calculate width to be used in webkit window.
+ private int calculateWindowWidth(int viewWidth, int textwrapWidth) {
+ int width = viewWidth;
+ if (mSettings.getUseWideViewPort()) {
+ if (mViewportWidth == -1) {
+ if (mSettings.getLayoutAlgorithm() ==
+ WebSettings.LayoutAlgorithm.NORMAL || mSettings.getUseFixedViewport()) {
+ width = WebView.DEFAULT_VIEWPORT_WIDTH;
+ } else {
+ /*
+ * if a page's minimum preferred width is wider than the
+ * given "w", use it instead to get better layout result. If
+ * we start a page with MAX_ZOOM_WIDTH, "w" will be always
+ * wider. If we start a page with screen width, due to the
+ * delay between {@link #didFirstLayout} and
+ * {@link #viewSizeChanged},
+ * {@link #nativeGetContentMinPrefWidth} will return a more
+ * accurate value than initial 0 to result a better layout.
+ * In the worse case, the native width will be adjusted when
+ * next zoom or screen orientation change happens.
+ */
+ width = Math.min(WebView.sMaxViewportWidth, Math.max(viewWidth,
+ Math.max(WebView.DEFAULT_VIEWPORT_WIDTH,
+ nativeGetContentMinPrefWidth())));
+ }
+ } else if (mViewportWidth > 0) {
+ if (mSettings.getUseFixedViewport()) {
+ // Use website specified or desired fixed viewport width.
+ width = mViewportWidth;
+ } else {
+ width = Math.max(viewWidth, mViewportWidth);
+ }
+ } else if (mSettings.getUseFixedViewport()) {
+ width = mWebView.getViewWidth();
+ } else {
+ width = textwrapWidth;
+ }
+ }
+ return width;
+ }
+
private void sendUpdateTextEntry() {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
@@ -2370,7 +2388,7 @@
// to syncing an incorrect height.
data.mHeight = mCurrentViewHeight == 0 ?
Math.round(mWebView.getViewHeight() / data.mScale)
- : mCurrentViewHeight * data.mWidth / viewportWidth;
+ : Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth);
data.mTextWrapWidth = Math.round(webViewWidth
/ mInitialViewState.mTextWrapScale);
data.mIgnoreHeight = false;
@@ -2696,4 +2714,5 @@
int slop);
private native void nativeAutoFillForm(int queryId);
+ private native void nativeScrollLayer(int layer, Rect rect);
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 4597727..86aef4c 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -361,6 +361,7 @@
// returns TRUE if zoom out succeeds and FALSE if no zoom changes.
private boolean zoom(float zoomMultiplier) {
+ mInitialZoomOverview = false;
// TODO: alternatively we can disallow this during draw history mode
mWebView.switchOutDrawHistory();
// Center zooming to the center of the screen.
@@ -378,6 +379,7 @@
* @return true if the new scale triggered an animation and false otherwise.
*/
public boolean startZoomAnimation(float scale, boolean reflowText) {
+ mInitialZoomOverview = false;
float oldScale = mActualScale;
mInitialScrollX = mWebView.getScrollX();
mInitialScrollY = mWebView.getScrollY();
@@ -421,6 +423,7 @@
* in progress by calling isFixedLengthAnimationInProgress().
*/
public void animateZoom(Canvas canvas) {
+ mInitialZoomOverview = false;
if (mZoomScale == 0) {
Log.w(LOGTAG, "A WebView is attempting to perform a fixed length "
+ "zoom animation when no zoom is in progress");
@@ -568,6 +571,8 @@
* C. If the page is in overmode then change to the default scale.
*/
public void handleDoubleTap(float lastTouchX, float lastTouchY) {
+ // User takes action, set initial zoom overview to false.
+ mInitialZoomOverview = false;
WebSettings settings = mWebView.getSettings();
if (!isDoubleTapEnabled()) {
return;
@@ -706,6 +711,7 @@
private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {
public boolean onScaleBegin(ScaleGestureDetector detector) {
+ mInitialZoomOverview = false;
dismissZoomPicker();
mWebView.mViewManager.startZoom();
mWebView.onPinchToZoomAnimationStart();
@@ -791,22 +797,30 @@
// scaleAll(), we need to post a Runnable to ensure requestLayout().
// Additionally, only update the text wrap scale if the width changed.
mWebView.post(new PostScale(w != ow &&
- !mWebView.getSettings().getUseFixedViewport()));
+ !mWebView.getSettings().getUseFixedViewport(), mInZoomOverview));
}
private class PostScale implements Runnable {
final boolean mUpdateTextWrap;
+ // Remember the zoom overview state right after rotation since
+ // it could be changed between the time this callback is initiated and
+ // the time it's actually run.
+ final boolean mInZoomOverviewBeforeSizeChange;
- public PostScale(boolean updateTextWrap) {
+ public PostScale(boolean updateTextWrap, boolean inZoomOverview) {
mUpdateTextWrap = updateTextWrap;
+ mInZoomOverviewBeforeSizeChange = inZoomOverview;
}
public void run() {
if (mWebView.getWebViewCore() != null) {
// we always force, in case our height changed, in which case we
// still want to send the notification over to webkit.
- setZoomScale(Math.max(mActualScale, getZoomOverviewScale()),
- mUpdateTextWrap, true);
+ // Keep overview mode unchanged when rotating.
+ final float zoomOverviewScale = getZoomOverviewScale();
+ final float newScale = (mInZoomOverviewBeforeSizeChange) ?
+ zoomOverviewScale : Math.max(mActualScale, zoomOverviewScale);
+ setZoomScale(newScale, mUpdateTextWrap, true);
// update the zoom buttons as the scale can be changed
updateZoomPicker();
}
@@ -864,12 +878,24 @@
if (!mMinZoomScaleFixed) {
mMinZoomScale = newZoomOverviewScale;
}
- // fit the content width to the current view. Ignore the rounding error case.
- if (!mWebView.drawHistory() && (mInitialZoomOverview || (mInZoomOverview
- && Math.abs((viewWidth * mInvActualScale) - mZoomOverviewWidth) > 1))) {
+ // fit the content width to the current view for the first new picture
+ // after first layout.
+ boolean scaleHasDiff = exceedsMinScaleIncrement(newZoomOverviewScale, mActualScale);
+ // Make sure the actual scale is no less than zoom overview scale.
+ boolean scaleLessThanOverview =
+ (newZoomOverviewScale - mActualScale) >= MINIMUM_SCALE_INCREMENT;
+ // Make sure mobile sites are correctly handled since mobile site will
+ // change content width after rotating.
+ boolean mobileSiteInOverview = mInZoomOverview &&
+ !exceedsMinScaleIncrement(newZoomOverviewScale, 1.0f);
+ if (!mWebView.drawHistory() &&
+ (mInitialZoomOverview || scaleLessThanOverview || mobileSiteInOverview) &&
+ scaleHasDiff && zoomOverviewWidthChanged) {
mInitialZoomOverview = false;
setZoomScale(newZoomOverviewScale, !willScaleTriggerZoom(mTextWrapScale) &&
!mWebView.getSettings().getUseFixedViewport());
+ } else {
+ mInZoomOverview = !scaleHasDiff;
}
}
@@ -1050,4 +1076,12 @@
public void setHardwareAccelerated() {
mHardwareAccelerated = true;
}
+
+ /**
+ * OnPageFinished called by webview when a page is fully loaded.
+ */
+ /* package*/ void onPageFinished(String url) {
+ // Turn off initial zoom overview flag when a page is fully loaded.
+ mInitialZoomOverview = false;
+ }
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 27020c5..eb53e56 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3267,9 +3267,10 @@
final int scrollY = mScrollY;
if (!mEdgeGlowTop.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth();
+ final int width = getWidth() - mListPadding.left - mListPadding.right;
- canvas.translate(0, Math.min(0, scrollY + mFirstPositionDistanceGuess));
+ canvas.translate(mListPadding.left,
+ Math.min(0, scrollY + mFirstPositionDistanceGuess));
mEdgeGlowTop.setSize(width, getHeight());
if (mEdgeGlowTop.draw(canvas)) {
invalidate();
@@ -3278,10 +3279,11 @@
}
if (!mEdgeGlowBottom.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth();
+ final int width = getWidth() - mListPadding.left - mListPadding.right;
final int height = getHeight();
- canvas.translate(-width, Math.max(height, scrollY + mLastPositionDistanceGuess));
+ canvas.translate(-width + mListPadding.left,
+ Math.max(height, scrollY + mLastPositionDistanceGuess));
canvas.rotate(180, width, 0);
mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.draw(canvas)) {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 3bdba62..27610b9f 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -92,6 +92,8 @@
static final boolean DEBUG = false;
static final String TAG = "AutoCompleteTextView";
+ static final int EXPAND_MAX = 3;
+
private CharSequence mHintText;
private TextView mHintView;
private int mHintResource;
@@ -1057,8 +1059,10 @@
if (!isPopupShowing()) {
// Make sure the list does not obscure the IME when shown for the first time.
mPopup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NEEDED);
+ mPopup.setListItemExpandMax(EXPAND_MAX);
}
mPopup.show();
+ mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
}
/**
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 13f0890..d75748f 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1422,11 +1422,11 @@
final int scrollX = mScrollX;
if (!mEdgeGlowLeft.isFinished()) {
final int restoreCount = canvas.save();
- final int height = getHeight();
+ final int height = getHeight() - mPaddingTop - mPaddingBottom;
canvas.rotate(270);
- canvas.translate(-height, Math.min(0, scrollX));
- mEdgeGlowLeft.setSize(getHeight(), getWidth());
+ canvas.translate(-height + mPaddingTop, Math.min(0, scrollX));
+ mEdgeGlowLeft.setSize(height, getWidth());
if (mEdgeGlowLeft.draw(canvas)) {
invalidate();
}
@@ -1435,10 +1435,10 @@
if (!mEdgeGlowRight.isFinished()) {
final int restoreCount = canvas.save();
final int width = getWidth();
- final int height = getHeight();
+ final int height = getHeight() - mPaddingTop - mPaddingBottom;
canvas.rotate(90);
- canvas.translate(0,
+ canvas.translate(-mPaddingTop,
-(Math.max(getScrollRange(), scrollX) + width));
mEdgeGlowRight.setSize(height, width);
if (mEdgeGlowRight.draw(canvas)) {
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 8811492..5642877 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -65,6 +65,7 @@
private boolean mDropDownAlwaysVisible = false;
private boolean mForceIgnoreOutsideTouch = false;
+ int mListItemExpandMaximum = Integer.MAX_VALUE;
private View mPromptView;
private int mPromptPosition = POSITION_PROMPT_ABOVE;
@@ -519,6 +520,7 @@
int heightSpec = 0;
boolean noInputMethod = isInputMethodNotNeeded();
+ mPopup.setAllowScrollingAnchorParent(!noInputMethod);
if (mPopup.isShowing()) {
if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
@@ -604,6 +606,7 @@
removePromptView();
mPopup.setContentView(null);
mDropDownList = null;
+ mHandler.removeCallbacks(mResizePopupRunnable);
}
/**
@@ -774,6 +777,16 @@
}
/**
+ * The maximum number of list items that can be visible and still have
+ * the list expand when touched.
+ *
+ * @param max Max number of items that can be visible and still allow the list to expand.
+ */
+ void setListItemExpandMax(int max) {
+ mListItemExpandMaximum = max;
+ }
+
+ /**
* Filter key down events. By forwarding key down events to this function,
* views using non-modal ListPopupWindow can have it handle key selection of items.
*
@@ -1209,8 +1222,11 @@
private class ResizePopupRunnable implements Runnable {
public void run() {
- mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
- show();
+ if (mDropDownList != null && mDropDownList.getCount() > mDropDownList.getChildCount() &&
+ mDropDownList.getChildCount() <= mListItemExpandMaximum) {
+ mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+ show();
+ }
}
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 439e0ca..4b858d0 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -90,6 +90,7 @@
private int mSplitTouchEnabled = -1;
private boolean mLayoutInScreen;
private boolean mClipToScreen;
+ private boolean mAllowScrollingAnchorParent = true;
private OnTouchListener mTouchInterceptor;
@@ -592,6 +593,16 @@
mClipToScreen = enabled;
setClippingEnabled(!enabled);
}
+
+ /**
+ * Allow PopupWindow to scroll the anchor's parent to provide more room
+ * for the popup. Enabled by default.
+ *
+ * @param enabled True to scroll the anchor's parent when more room is desired by the popup.
+ */
+ void setAllowScrollingAnchorParent(boolean enabled) {
+ mAllowScrollingAnchorParent = enabled;
+ }
/**
* <p>Indicates whether the popup window supports splitting touches.</p>
@@ -1049,11 +1060,13 @@
// if the drop down disappears at the bottom of the screen. we try to
// scroll a parent scrollview or move the drop down back up on top of
// the edit box
- int scrollX = anchor.getScrollX();
- int scrollY = anchor.getScrollY();
- Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
- scrollY + mPopupHeight + anchor.getHeight() + yoff);
- anchor.requestRectangleOnScreen(r, true);
+ if (mAllowScrollingAnchorParent) {
+ int scrollX = anchor.getScrollX();
+ int scrollY = anchor.getScrollY();
+ Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
+ scrollY + mPopupHeight + anchor.getHeight() + yoff);
+ anchor.requestRectangleOnScreen(r, true);
+ }
// now we re-evaluate the space available, and decide from that
// whether the pop-up will go above or below the anchor.
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index d1cfcec..4cc4a27 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1470,9 +1470,9 @@
final int scrollY = mScrollY;
if (!mEdgeGlowTop.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth();
+ final int width = getWidth() - mPaddingLeft - mPaddingRight;
- canvas.translate(0, Math.min(0, scrollY));
+ canvas.translate(mPaddingLeft, Math.min(0, scrollY));
mEdgeGlowTop.setSize(width, getHeight());
if (mEdgeGlowTop.draw(canvas)) {
invalidate();
@@ -1481,10 +1481,11 @@
}
if (!mEdgeGlowBottom.isFinished()) {
final int restoreCount = canvas.save();
- final int width = getWidth();
+ final int width = getWidth() - mPaddingLeft - mPaddingRight;
final int height = getHeight();
- canvas.translate(-width, Math.max(getScrollRange(), scrollY) + height);
+ canvas.translate(-width + mPaddingLeft,
+ Math.max(getScrollRange(), scrollY) + height);
canvas.rotate(180, width, 0);
mEdgeGlowBottom.setSize(width, height);
if (mEdgeGlowBottom.draw(canvas)) {
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index f051b77..22edcd0 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -394,7 +394,6 @@
if (mIconifiedByDefault == iconified) return;
mIconifiedByDefault = iconified;
updateViewsVisibility(iconified);
- setImeVisibility(!iconified);
}
/**
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 6a09d35..e6cf31e 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -1207,6 +1207,7 @@
void invalidateGlobalRegion(View v, Rect r) {
// We need to make a new rect here, so as not to modify the one passed
globalInvalidateRect.set(r);
+ globalInvalidateRect.union(0, 0, getWidth(), getHeight());
View p = v;
if (!(v.getParent() != null && v.getParent() instanceof View)) return;
@@ -1223,8 +1224,9 @@
firstPass = false;
p = (View) p.getParent();
parentRect.set(p.getScrollX(), p.getScrollY(),
- p.getWidth() + p.getScrollX(), p.getHeight() + p.getScrollY());
-
+ p.getWidth() + p.getScrollX(), p.getHeight() + p.getScrollY());
+ p.invalidate(globalInvalidateRect.left, globalInvalidateRect.top,
+ globalInvalidateRect.right, globalInvalidateRect.bottom);
}
p.invalidate(globalInvalidateRect.left, globalInvalidateRect.top,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 28b106b..d90d5be 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -304,15 +304,19 @@
}
InputMethodState mInputMethodState;
- int mTextSelectHandleLeftRes;
- int mTextSelectHandleRightRes;
- int mTextSelectHandleRes;
- int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
- int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
+ private int mTextSelectHandleLeftRes;
+ private int mTextSelectHandleRightRes;
+ private int mTextSelectHandleRes;
+ private int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
+ private int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
- Drawable mSelectHandleLeft;
- Drawable mSelectHandleRight;
- Drawable mSelectHandleCenter;
+ private int mCursorDrawableRes;
+ private final Drawable[] mCursorDrawable = new Drawable[2];
+ private int mCursorCount; // Actual current number of used mCursorDrawable: 0, 1 or 2
+
+ private Drawable mSelectHandleLeft;
+ private Drawable mSelectHandleRight;
+ private Drawable mSelectHandleCenter;
private int mLastDownPositionX, mLastDownPositionY;
private Callback mCustomSelectionActionModeCallback;
@@ -742,6 +746,10 @@
}
break;
+ case com.android.internal.R.styleable.TextView_textCursorDrawable:
+ mCursorDrawableRes = a.getResourceId(attr, 0);
+ break;
+
case com.android.internal.R.styleable.TextView_textSelectHandleLeft:
mTextSelectHandleLeftRes = a.getResourceId(attr, 0);
break;
@@ -3770,33 +3778,40 @@
if (mHighlightPathBogus) {
invalidateCursor();
} else {
- synchronized (sTempRect) {
- /*
- * The reason for this concern about the thickness of the
- * cursor and doing the floor/ceil on the coordinates is that
- * some EditTexts (notably textfields in the Browser) have
- * anti-aliased text where not all the characters are
- * necessarily at integer-multiple locations. This should
- * make sure the entire cursor gets invalidated instead of
- * sometimes missing half a pixel.
- */
+ final int horizontalPadding = getCompoundPaddingLeft();
+ final int verticalPadding = getExtendedPaddingTop() + getVerticalOffset(true);
- float thick = FloatMath.ceil(mTextPaint.getStrokeWidth());
- if (thick < 1.0f) {
- thick = 1.0f;
+ if (mCursorCount == 0) {
+ synchronized (sTempRect) {
+ /*
+ * The reason for this concern about the thickness of the
+ * cursor and doing the floor/ceil on the coordinates is that
+ * some EditTexts (notably textfields in the Browser) have
+ * anti-aliased text where not all the characters are
+ * necessarily at integer-multiple locations. This should
+ * make sure the entire cursor gets invalidated instead of
+ * sometimes missing half a pixel.
+ */
+ float thick = FloatMath.ceil(mTextPaint.getStrokeWidth());
+ if (thick < 1.0f) {
+ thick = 1.0f;
+ }
+
+ thick /= 2.0f;
+
+ mHighlightPath.computeBounds(sTempRect, false);
+
+ invalidate((int) FloatMath.floor(horizontalPadding + sTempRect.left - thick),
+ (int) FloatMath.floor(verticalPadding + sTempRect.top - thick),
+ (int) FloatMath.ceil(horizontalPadding + sTempRect.right + thick),
+ (int) FloatMath.ceil(verticalPadding + sTempRect.bottom + thick));
}
-
- thick /= 2;
-
- mHighlightPath.computeBounds(sTempRect, false);
-
- int left = getCompoundPaddingLeft();
- int top = getExtendedPaddingTop() + getVerticalOffset(true);
-
- invalidate((int) FloatMath.floor(left + sTempRect.left - thick),
- (int) FloatMath.floor(top + sTempRect.top - thick),
- (int) FloatMath.ceil(left + sTempRect.right + thick),
- (int) FloatMath.ceil(top + sTempRect.bottom + thick));
+ } else {
+ for (int i = 0; i < mCursorCount; i++) {
+ Rect bounds = mCursorDrawable[i].getBounds();
+ invalidate(bounds.left + horizontalPadding, bounds.top + verticalPadding,
+ bounds.right + horizontalPadding, bounds.bottom + verticalPadding);
+ }
}
}
}
@@ -3836,13 +3851,23 @@
line2 = mLayout.getLineForOffset(last);
int bottom = mLayout.getLineTop(line2 + 1);
- int voffset = getVerticalOffset(true);
- int left = getCompoundPaddingLeft() + mScrollX;
- invalidate(left, top + voffset + getExtendedPaddingTop(),
- left + getWidth() - getCompoundPaddingLeft() -
- getCompoundPaddingRight(),
- bottom + voffset + getExtendedPaddingTop());
+ final int horizontalPadding = getCompoundPaddingLeft();
+ final int verticalPadding = getExtendedPaddingTop() + getVerticalOffset(true);
+
+ // If used, the cursor drawables can have an arbitrary dimension that can go beyond
+ // the invalidated lines specified above.
+ for (int i = 0; i < mCursorCount; i++) {
+ Rect bounds = mCursorDrawable[i].getBounds();
+ top = Math.min(top, bounds.top);
+ bottom = Math.max(bottom, bounds.bottom);
+ // Horizontal bounds are already full width, no need to update
+ }
+
+ invalidate(horizontalPadding + mScrollX, top + verticalPadding,
+ horizontalPadding + mScrollX + getWidth() -
+ getCompoundPaddingLeft() - getCompoundPaddingRight(),
+ bottom + verticalPadding);
}
}
}
@@ -4346,6 +4371,7 @@
Path highlight = null;
int selStart = -1, selEnd = -1;
+ boolean drawCursor = false;
// If there is no movement method, then there can be no selection.
// Check that first and attempt to skip everything having to do with
@@ -4366,6 +4392,7 @@
if (mHighlightPathBogus) {
mHighlightPath.reset();
mLayout.getCursorPath(selStart, mHighlightPath, mText);
+ updateCursorsPositions();
mHighlightPathBogus = false;
}
@@ -4376,8 +4403,8 @@
(mCurrentAlpha * Color.alpha(cursorcolor)) / 255);
}
mHighlightPaint.setStyle(Paint.Style.STROKE);
-
highlight = mHighlightPath;
+ drawCursor = true;
}
} else {
if (mHighlightPathBogus) {
@@ -4460,6 +4487,13 @@
mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
}
+ if (drawCursor) {
+ drawCursor(canvas, cursorOffsetVertical);
+ // Rely on the drawable entirely, do not draw the cursor line.
+ // Has to be done after the IMM related code above which relies on the highlight.
+ highlight = null;
+ }
+
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
if (mMarquee != null && mMarquee.shouldDrawGhost()) {
@@ -4478,6 +4512,52 @@
updateCursorControllerPositions();
}
+ private void updateCursorsPositions() {
+ if (mCursorDrawableRes == 0) return;
+
+ final int offset = getSelectionStart();
+ final int line = mLayout.getLineForOffset(offset);
+ final int top = mLayout.getLineTop(line);
+ final int bottom = mLayout.getLineTop(line + 1);
+
+ mCursorCount = mLayout.isLevelBoundary(offset) ? 2 : 1;
+
+ int middle = bottom;
+ if (mCursorCount == 2) {
+ // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
+ middle = (top + bottom) >> 1;
+ }
+
+ updateCursorPosition(0, top, middle, mLayout.getPrimaryHorizontal(offset));
+
+ if (mCursorCount == 2) {
+ updateCursorPosition(1, middle, bottom, mLayout.getSecondaryHorizontal(offset));
+ }
+ }
+
+ private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
+ if (mCursorDrawable[cursorIndex] == null)
+ mCursorDrawable[cursorIndex] = mContext.getResources().getDrawable(mCursorDrawableRes);
+
+ if (mTempRect == null) mTempRect = new Rect();
+
+ mCursorDrawable[cursorIndex].getPadding(mTempRect);
+ final int width = mCursorDrawable[cursorIndex].getIntrinsicWidth();
+ horizontal = Math.max(0.5f, horizontal - 0.5f);
+ final int left = (int) (horizontal) - mTempRect.left;
+ mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
+ bottom + mTempRect.bottom);
+ }
+
+ private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
+ final boolean translate = cursorOffsetVertical != 0;
+ if (translate) canvas.translate(0, cursorOffsetVertical);
+ for (int i = 0; i < mCursorCount; i++) {
+ mCursorDrawable[i].draw(canvas);
+ }
+ if (translate) canvas.translate(0, -cursorOffsetVertical);
+ }
+
/**
* Update the positions of the CursorControllers. Needed by WebTextView,
* which does not draw.
@@ -8699,7 +8779,7 @@
}
mDrawable = mSelectHandleLeft;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = (handleWidth * 3) / 4;
+ mHotspotX = handleWidth * 3.0f / 4.0f;
break;
}
@@ -8710,7 +8790,7 @@
}
mDrawable = mSelectHandleRight;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 4;
+ mHotspotX = handleWidth / 4.0f;
break;
}
@@ -8722,7 +8802,7 @@
}
mDrawable = mSelectHandleCenter;
handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 2;
+ mHotspotX = handleWidth / 2.0f;
mIsInsertionHandle = true;
break;
}
@@ -8937,8 +9017,8 @@
final int lineBottom = mLayout.getLineBottom(line);
final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - mHotspotX)
- + TextView.this.mScrollX;
+ bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX) +
+ TextView.this.mScrollX;
bounds.top = (bottom ? lineBottom : lineTop - mHeight) + TextView.this.mScrollY;
bounds.right = bounds.left + width;
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 18d1825..029d690 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -43,8 +43,8 @@
* or 'P' to pick. For a dialog using this view, see
* {@link android.app.TimePickerDialog}.
*<p>
- * See the <a href="{@docRoot}
- * resources/tutorials/views/hello-timepicker.html">Time Picker tutorial</a>.
+ * See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
+ * tutorial</a>.
* </p>
*/
@Widget
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index b3b80f6..1cca21d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -194,7 +194,7 @@
int mPhoneSignalStrengthBin = -1;
int mPhoneSignalStrengthBinRaw = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
- new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
+ new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
StopwatchTimer mPhoneSignalScanningTimer;
@@ -1659,7 +1659,7 @@
}
void stopAllSignalStrengthTimersLocked(int except) {
- for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
if (i == except) {
continue;
}
@@ -1674,7 +1674,7 @@
// In this case we will always be STATE_OUT_OF_SERVICE, so need
// to infer that we are scanning from other data.
if (state == ServiceState.STATE_OUT_OF_SERVICE
- && signalBin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
state = ServiceState.STATE_IN_SERVICE;
}
}
@@ -1694,7 +1694,7 @@
// In this case we will always be STATE_OUT_OF_SERVICE, so need
// to infer that we are scanning from other data.
if (state == ServiceState.STATE_OUT_OF_SERVICE
- && bin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
state = ServiceState.STATE_IN_SERVICE;
}
}
@@ -1711,7 +1711,7 @@
// bin and have the scanning bit set.
} else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
scanning = true;
- bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (!mPhoneSignalScanningTimer.isRunningLocked()) {
mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
newHistory = true;
@@ -1775,24 +1775,7 @@
public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
// Bin the strength.
- int bin;
-
- if (!signalStrength.isGsm()) {
- int dBm = signalStrength.getCdmaDbm();
- if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
- else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
- else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
- else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
- else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- } else {
- int asu = signalStrength.getGsmSignalStrength();
- if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
- else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
- else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
- else bin = SIGNAL_STRENGTH_POOR;
- }
-
+ int bin = signalStrength.getLevel();
updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
}
@@ -3903,7 +3886,7 @@
}
mInputEventCounter = new Counter(mUnpluggables);
mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
}
mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
@@ -4017,7 +4000,7 @@
mPhoneOnTimer.reset(this, false);
mAudioOnTimer.reset(this, false);
mVideoOnTimer.reset(this, false);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].reset(this, false);
}
mPhoneSignalScanningTimer.reset(this, false);
@@ -4780,7 +4763,7 @@
mInputEventCounter.readSummaryFromParcelLocked(in);
mPhoneOn = false;
mPhoneOnTimer.readSummaryFromParcelLocked(in);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
}
mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
@@ -4973,7 +4956,7 @@
}
mInputEventCounter.writeSummaryFromParcelLocked(out);
mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@@ -5172,7 +5155,7 @@
mInputEventCounter = new Counter(mUnpluggables, in);
mPhoneOn = false;
mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
null, mUnpluggables, in);
}
@@ -5285,7 +5268,7 @@
}
mInputEventCounter.writeToParcel(out);
mPhoneOnTimer.writeToParcel(out, batteryRealtime);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
}
mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
@@ -5382,7 +5365,7 @@
mInputEventCounter.logState(pr, " ");
pr.println("*** Phone timer:");
mPhoneOnTimer.logState(pr, " ");
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
pr.println("*** Signal strength #" + i + ":");
mPhoneSignalStrengthsTimer[i].logState(pr, " ");
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 1f93eac..04a059e 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -36,14 +36,15 @@
* @hide
*/
public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener,
- ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener {
+ ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener,
+ View.OnAttachStateChangeListener {
private static final String TAG = "MenuPopupHelper";
private Context mContext;
private ListPopupWindow mPopup;
private MenuBuilder mMenu;
private int mPopupMaxWidth;
- private WeakReference<View> mAnchorView;
+ private View mAnchorView;
private boolean mOverflowOnly;
private ViewTreeObserver mTreeObserver;
@@ -66,13 +67,11 @@
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mPopupMaxWidth = metrics.widthPixels / 2;
- if (anchorView != null) {
- mAnchorView = new WeakReference<View>(anchorView);
- }
+ mAnchorView = anchorView;
}
public void setAnchorView(View anchor) {
- mAnchorView = new WeakReference<View>(anchor);
+ mAnchorView = anchor;
}
public void show() {
@@ -92,17 +91,19 @@
mPopup.setAdapter(adapter);
mPopup.setModal(true);
- View anchor = mAnchorView != null ? mAnchorView.get() : null;
+ View anchor = mAnchorView;
if (anchor == null && mMenu instanceof SubMenuBuilder) {
SubMenuBuilder subMenu = (SubMenuBuilder) mMenu;
final MenuItemImpl itemImpl = (MenuItemImpl) subMenu.getItem();
anchor = itemImpl.getItemView(MenuBuilder.TYPE_ACTION_BUTTON, null);
- mAnchorView = new WeakReference<View>(anchor);
+ mAnchorView = anchor;
}
if (anchor != null) {
- mTreeObserver = anchor.getViewTreeObserver();
- mTreeObserver.addOnGlobalLayoutListener(this);
+ final boolean addGlobalListener = mTreeObserver == null;
+ mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest
+ if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
+ anchor.addOnAttachStateChangeListener(this);
mPopup.setAnchorView(anchor);
} else {
return false;
@@ -124,9 +125,11 @@
public void onDismiss() {
mPopup = null;
if (mTreeObserver != null) {
- mTreeObserver.removeGlobalOnLayoutListener(MenuPopupHelper.this);
+ if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
mTreeObserver = null;
}
+ mAnchorView.removeOnAttachStateChangeListener(this);
}
public boolean isShowing() {
@@ -134,6 +137,8 @@
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (!isShowing()) return;
+
MenuItem item = null;
if (mOverflowOnly) {
item = mMenu.getOverflowItem(position);
@@ -183,17 +188,27 @@
@Override
public void onGlobalLayout() {
- if (!isShowing()) {
- mTreeObserver.removeGlobalOnLayoutListener(this);
- mTreeObserver = null;
- } else {
- final View anchor = mAnchorView != null ? mAnchorView.get() : null;
- if (anchor != null && !anchor.isShown()) {
+ if (isShowing()) {
+ final View anchor = mAnchorView;
+ if (anchor == null || !anchor.isShown()) {
dismiss();
- } else {
+ } else if (isShowing()) {
// Recompute window size and position
mPopup.show();
}
}
}
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ }
+ v.removeOnAttachStateChangeListener(this);
+ }
}
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 0b765fd..c72d0e8 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -27,6 +27,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.MotionEvent.PointerCoords;
import java.util.ArrayList;
@@ -43,7 +44,7 @@
private boolean mCurDown;
// Most recent coordinates.
- private MotionEvent.PointerCoords mCoords = new MotionEvent.PointerCoords();
+ private PointerCoords mCoords = new PointerCoords();
// Most recent velocity.
private float mXVelocity;
@@ -86,6 +87,7 @@
private int mMaxNumPointers;
private int mActivePointerId;
private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
+ private final PointerCoords mHoverCoords = new PointerCoords();
private final VelocityTracker mVelocity;
@@ -327,7 +329,10 @@
.append(" ToolMajor=").append(coords.toolMajor, 3)
.append(" ToolMinor=").append(coords.toolMinor, 3)
.append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1)
- .append("deg").toString());
+ .append("deg")
+ .append(" VScroll=").append(coords.getAxisValue(MotionEvent.AXIS_VSCROLL), 1)
+ .append(" HScroll=").append(coords.getAxisValue(MotionEvent.AXIS_HSCROLL), 1)
+ .toString());
}
public void addTouchEvent(MotionEvent event) {
@@ -383,9 +388,11 @@
}
final int NI = event.getPointerCount();
-
+
+ final boolean hover = (action == MotionEvent.ACTION_HOVER_MOVE);
mCurDown = action != MotionEvent.ACTION_UP
- && action != MotionEvent.ACTION_CANCEL;
+ && action != MotionEvent.ACTION_CANCEL
+ && !hover;
mCurNumPointers = mCurDown ? NI : 0;
if (mMaxNumPointers < mCurNumPointers) {
mMaxNumPointers = mCurNumPointers;
@@ -396,22 +403,27 @@
for (int i=0; i<NI; i++) {
final int id = event.getPointerId(i);
- final PointerState ps = mPointers.get(id);
+ final PointerState ps = hover ? null : mPointers.get(id);
+ final PointerCoords coords = ps != null ? ps.mCoords : mHoverCoords;
final int N = event.getHistorySize();
for (int j=0; j<N; j++) {
- event.getHistoricalPointerCoords(i, j, ps.mCoords);
+ event.getHistoricalPointerCoords(i, j, coords);
if (mPrintCoords) {
- logPointerCoords(ps.mCoords, id);
+ logPointerCoords(coords, id);
}
- ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
+ if (ps != null) {
+ ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
+ }
}
- event.getPointerCoords(i, ps.mCoords);
+ event.getPointerCoords(i, coords);
if (mPrintCoords) {
- logPointerCoords(ps.mCoords, id);
+ logPointerCoords(coords, id);
}
- ps.addTrace(ps.mCoords.x, ps.mCoords.y);
- ps.mXVelocity = mVelocity.getXVelocity(id);
- ps.mYVelocity = mVelocity.getYVelocity(id);
+ if (ps != null) {
+ ps.addTrace(coords.x, coords.y);
+ ps.mXVelocity = mVelocity.getXVelocity(id);
+ ps.mYVelocity = mVelocity.getYVelocity(id);
+ }
}
if (action == MotionEvent.ACTION_UP
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
index bf23650..acf858a 100755
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
@@ -89,40 +89,40 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
/* in */
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mHandsfreeAgRfcommChannel =
+ field_mHandsfreeAgRfcommChannel =
get_field(env, clazz, "mHandsfreeAgRfcommChannel", "I");
- field_mHeadsetAgRfcommChannel =
+ field_mHeadsetAgRfcommChannel =
get_field(env, clazz, "mHeadsetAgRfcommChannel", "I");
/* out */
- field_mConnectingHeadsetAddress =
- get_field(env, clazz,
+ field_mConnectingHeadsetAddress =
+ get_field(env, clazz,
"mConnectingHeadsetAddress", "Ljava/lang/String;");
- field_mConnectingHeadsetRfcommChannel =
+ field_mConnectingHeadsetRfcommChannel =
get_field(env, clazz, "mConnectingHeadsetRfcommChannel", "I");
- field_mConnectingHeadsetSocketFd =
+ field_mConnectingHeadsetSocketFd =
get_field(env, clazz, "mConnectingHeadsetSocketFd", "I");
- field_mConnectingHandsfreeAddress =
- get_field(env, clazz,
+ field_mConnectingHandsfreeAddress =
+ get_field(env, clazz,
"mConnectingHandsfreeAddress", "Ljava/lang/String;");
- field_mConnectingHandsfreeRfcommChannel =
+ field_mConnectingHandsfreeRfcommChannel =
get_field(env, clazz, "mConnectingHandsfreeRfcommChannel", "I");
- field_mConnectingHandsfreeSocketFd =
+ field_mConnectingHandsfreeSocketFd =
get_field(env, clazz, "mConnectingHandsfreeSocketFd", "I");
- field_mTimeoutRemainingMs =
+ field_mTimeoutRemainingMs =
get_field(env, clazz, "mTimeoutRemainingMs", "I");
#endif
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -150,7 +150,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -165,7 +165,7 @@
static int set_nb(int sk, bool nb) {
int flags = fcntl(sk, F_GETFL);
if (flags < 0) {
- LOGE("Can't get socket flags with fcntl(): %s (%d)",
+ LOGE("Can't get socket flags with fcntl(): %s (%d)",
strerror(errno), errno);
close(sk);
return -1;
@@ -255,7 +255,7 @@
static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
jint timeout_ms) {
-// LOGV(__FUNCTION__);
+// LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
env->SetIntField(object, field_mTimeoutRemainingMs, timeout_ms);
@@ -264,11 +264,11 @@
native_data_t *nat = get_native_data(env, object);
#if USE_ACCEPT_DIRECTLY
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
struct timeval tv;
int len = sizeof(tv);
- if (getsockopt(nat->hf_ag_rfcomm_channel,
+ if (getsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
LOGE("getsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -276,12 +276,12 @@
errno);
return JNI_FALSE;
}
- LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
+ LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
if (timeout_ms >= 0) {
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = 1000 * (timeout_ms % 1000);
- if (setsockopt(nat->hf_ag_rfcomm_channel,
+ if (setsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
LOGE("setsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -289,11 +289,11 @@
errno);
return JNI_FALSE;
}
- LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
+ LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
}
- if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
+ if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel))
@@ -309,13 +309,13 @@
FD_ZERO(&rset);
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hf_ag_rfcomm_sock, &rset);
}
if (nat->hs_ag_rfcomm_channel > 0) {
- LOGI("Setting HS AG server socket to RFCOMM port %d!",
+ LOGI("Setting HS AG server socket to RFCOMM port %d!",
nat->hs_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hs_ag_rfcomm_sock, &rset);
@@ -330,7 +330,7 @@
to.tv_sec = timeout_ms / 1000;
to.tv_usec = 1000 * (timeout_ms % 1000);
}
- n = select(MAX(nat->hf_ag_rfcomm_sock,
+ n = select(MAX(nat->hf_ag_rfcomm_sock,
nat->hs_ag_rfcomm_sock) + 1,
&rset,
NULL,
@@ -354,7 +354,7 @@
return JNI_FALSE;
}
- n = on_accept_set_fields(env, object,
+ n = on_accept_set_fields(env, object,
&rset, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
@@ -371,7 +371,7 @@
struct pollfd fds[2];
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
-// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
// nat->hf_ag_rfcomm_sock,
// nat->hf_ag_rfcomm_channel);
fds[cnt].fd = nat->hf_ag_rfcomm_sock;
@@ -379,7 +379,7 @@
cnt++;
}
if (nat->hs_ag_rfcomm_channel > 0) {
-// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
// nat->hs_ag_rfcomm_sock,
// nat->hs_ag_rfcomm_channel);
fds[cnt].fd = nat->hs_ag_rfcomm_sock;
@@ -411,7 +411,7 @@
if (fds[cnt].fd == nat->hf_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HF connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel);
@@ -421,7 +421,7 @@
else if (fds[cnt].fd == nat->hs_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HS connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHeadsetSocketFd,
field_mConnectingHeadsetAddress,
field_mConnectingHeadsetRfcommChannel);
@@ -444,7 +444,7 @@
}
static jboolean setUpListeningSocketsNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -509,7 +509,7 @@
private native void tearDownListeningSocketsNative();
*/
static void tearDownListeningSocketsNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 31ebf8c..b87f7c4 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -66,7 +66,7 @@
static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = asocket_init(fd);
@@ -85,7 +85,7 @@
static void initSocketNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
int lm = 0;
@@ -161,7 +161,7 @@
static void connectNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jint type;
@@ -240,7 +240,7 @@
/* Returns errno instead of throwing, so java can check errno */
static int bindListenNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jint type;
socklen_t addr_sz;
@@ -307,7 +307,7 @@
static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
jint type;
@@ -380,7 +380,7 @@
static jint availableNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int available;
struct asocket *s = get_socketData(env, obj);
@@ -403,7 +403,7 @@
static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -446,7 +446,7 @@
static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -488,7 +488,7 @@
static void abortNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
if (!s)
@@ -504,7 +504,7 @@
static void destroyNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
int fd = s->fd;
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
index 4e9fbaf..bbf1ae5 100644
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ b/core/jni/android_bluetooth_HeadsetBase.cpp
@@ -180,7 +180,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
@@ -191,7 +191,7 @@
static void initializeNativeDataNative(JNIEnv* env, jobject object,
jint socketFd) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -213,7 +213,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -226,7 +226,7 @@
static jboolean connectNative(JNIEnv *env, jobject obj)
{
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
int lm;
struct sockaddr_rc addr;
@@ -278,7 +278,7 @@
}
static jint connectAsyncNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -357,7 +357,7 @@
static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -463,7 +463,7 @@
}
static void disconnectNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, obj);
if (nat->rfcomm_sock >= 0) {
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index dfa36ce..0c84f11 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -130,6 +130,33 @@
"/sys/class/net/ppp0/statistics/rx_bytes");
}
+static jlong getData(JNIEnv* env, char *what, jstring interface) {
+ char filename[80];
+ jboolean isCopy;
+
+ const char *interfaceStr = env->GetStringUTFChars(interface, &isCopy);
+ snprintf(filename, sizeof(filename), "/sys/class/net/%s/statistics/%s", interfaceStr, what);
+
+ return readNumber(filename);
+}
+
+static jlong getTxPackets(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "tx_packets", interface);
+}
+
+static jlong getRxPackets(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "rx_packets", interface);
+}
+
+static jlong getTxBytes(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "tx_bytes", interface);
+}
+
+static jlong getRxBytes(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "rx_bytes", interface);
+}
+
+
// Total stats are read less often, so we're willing to put up
// with listing the directory and concatenating filenames.
@@ -288,6 +315,10 @@
{"getMobileRxPackets", "()J", (void*) getMobileRxPackets},
{"getMobileTxBytes", "()J", (void*) getMobileTxBytes},
{"getMobileRxBytes", "()J", (void*) getMobileRxBytes},
+ {"getTxPackets", "(Ljava/lang/String;)J", (void*) getTxPackets},
+ {"getRxPackets", "(Ljava/lang/String;)J", (void*) getRxPackets},
+ {"getTxBytes", "(Ljava/lang/String;)J", (void*) getTxBytes},
+ {"getRxBytes", "(Ljava/lang/String;)J", (void*) getRxBytes},
{"getTotalTxPackets", "()J", (void*) getTotalTxPackets},
{"getTotalRxPackets", "()J", (void*) getTotalRxPackets},
{"getTotalTxBytes", "()J", (void*) getTotalTxBytes},
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 58b5686..fc806a5 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -31,25 +31,6 @@
static jboolean sScanModeActive = false;
-//TODO: check general errors in addition to overflow on snprintf
-
-/*
- * The following remembers the jfieldID's of the fields
- * of the DhcpInfo Java object, so that we don't have
- * to look them up every time.
- */
-static struct fieldIds {
- jclass dhcpInfoClass;
- jmethodID constructorId;
- jfieldID ipaddress;
- jfieldID gateway;
- jfieldID netmask;
- jfieldID dns1;
- jfieldID dns2;
- jfieldID serverAddress;
- jfieldID leaseDuration;
-} dhcpInfoFieldIds;
-
static int doCommand(const char *cmd, char *replybuf, int replybuflen)
{
size_t reply_len = replybuflen - 1;
@@ -575,29 +556,6 @@
return doBooleanCommand(cmdstr, "OK");
}
-
-static jboolean android_net_wifi_doDhcpRequest(JNIEnv* env, jobject clazz, jobject info)
-{
- jint ipaddr, gateway, mask, dns1, dns2, server, lease;
- jboolean succeeded = ((jboolean)::do_dhcp_request(&ipaddr, &gateway, &mask,
- &dns1, &dns2, &server, &lease) == 0);
- if (succeeded && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
- env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
- env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
- env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
- env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
- env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
- env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
- env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
- }
- return succeeded;
-}
-
-static jstring android_net_wifi_getDhcpError(JNIEnv* env, jobject clazz)
-{
- return env->NewStringUTF(::get_dhcp_error_string());
-}
-
// ----------------------------------------------------------------------------
/*
@@ -665,8 +623,6 @@
(void*) android_net_wifi_setSuspendOptimizationsCommand},
{ "setCountryCodeCommand", "(Ljava/lang/String;)Z",
(void*) android_net_wifi_setCountryCodeCommand},
- { "doDhcpRequest", "(Landroid/net/DhcpInfo;)Z", (void*) android_net_wifi_doDhcpRequest },
- { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_wifi_getDhcpError },
};
int register_android_net_wifi_WifiManager(JNIEnv* env)
@@ -674,18 +630,6 @@
jclass wifi = env->FindClass(WIFI_PKG_NAME);
LOG_FATAL_IF(wifi == NULL, "Unable to find class " WIFI_PKG_NAME);
- dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo");
- if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
- dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V");
- dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I");
- dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I");
- dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I");
- dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
- dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
- dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I");
- dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I");
- }
-
return AndroidRuntime::registerNativeMethods(env,
WIFI_PKG_NAME, gWifiMethods, NELEM(gWifiMethods));
}
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index 8c795af..1851ad6 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -61,7 +61,7 @@
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -88,7 +88,7 @@
static void cleanupNative(JNIEnv* env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
dbus_connection_close(nat->conn);
env->DeleteGlobalRef(nat->me);
@@ -101,7 +101,7 @@
static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
DBusMessage *msg, *reply;
DBusError err;
@@ -132,7 +132,7 @@
static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
int len = env->GetStringLength(path) + 1;
@@ -153,7 +153,7 @@
static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
@@ -171,7 +171,7 @@
static jboolean suspendSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -187,7 +187,7 @@
static jboolean resumeSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -203,7 +203,7 @@
static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -219,7 +219,7 @@
static jboolean avrcpVolumeDownNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -278,7 +278,7 @@
}
void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index fd12c2d7..afaade8 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -88,7 +88,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
@@ -147,7 +147,7 @@
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -175,7 +175,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -216,7 +216,7 @@
}
static jboolean setUpEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
dbus_threads_init_default();
@@ -395,7 +395,7 @@
}
static void tearDownEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
DBusMessage *msg, *reply;
@@ -1229,7 +1229,7 @@
#ifdef HAVE_BLUETOOTH
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address = (const char *)user;
@@ -1298,7 +1298,7 @@
}
void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address= (const char *)user;
@@ -1328,7 +1328,7 @@
}
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1354,7 +1354,7 @@
}
void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
const char *address = (const char *) user;
native_data_t *nat = (native_data_t *) n;
@@ -1387,7 +1387,7 @@
}
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1426,7 +1426,7 @@
}
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index bf0504f..158e475 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -1,16 +1,16 @@
/*
** Copyright 2006, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
@@ -93,7 +93,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mEventLoop = get_field(env, clazz, "mEventLoop",
@@ -105,7 +105,7 @@
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -144,7 +144,7 @@
// This function is called when the adapter is enabled.
static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -167,7 +167,7 @@
}
static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -181,7 +181,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -193,7 +193,7 @@
}
static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -205,7 +205,7 @@
static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -251,7 +251,7 @@
}
static void stopDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -297,7 +297,7 @@
}
static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
DBusError err;
@@ -338,7 +338,7 @@
static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -374,7 +374,7 @@
static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -411,7 +411,7 @@
jstring path,
jstring pattern, jint attr_id) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
struct event_loop_native_data_t *eventLoopNat =
@@ -437,7 +437,7 @@
static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -469,7 +469,7 @@
}
static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -492,7 +492,7 @@
static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_enable();
#endif
return -1;
@@ -500,7 +500,7 @@
static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_disable();
#endif
return -1;
@@ -508,7 +508,7 @@
static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_is_enabled();
#endif
return -1;
@@ -518,7 +518,7 @@
jstring address, bool confirm,
int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -549,7 +549,7 @@
static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
int passkey, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -576,7 +576,7 @@
static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
jbyteArray hash, jbyteArray randomizer, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -610,7 +610,7 @@
static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
jstring pin, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -640,7 +640,7 @@
static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
jstring address, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -666,7 +666,7 @@
jstring path)
{
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -705,7 +705,7 @@
static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -741,7 +741,7 @@
static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg;
@@ -808,7 +808,7 @@
static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
jstring key, void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *reply, *msg;
@@ -863,7 +863,7 @@
static jboolean createDeviceNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -894,7 +894,7 @@
static jboolean discoverServicesNative(JNIEnv *env, jobject object,
jstring path, jstring pattern) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -955,7 +955,7 @@
static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray uuids) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *reply = NULL;
@@ -979,7 +979,7 @@
static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray handles) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jint *values = env->GetIntArrayElements(handles, NULL);
@@ -1002,7 +1002,7 @@
static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1027,7 +1027,7 @@
}
static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1045,7 +1045,7 @@
static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
jint num_slots) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1064,7 +1064,7 @@
}
static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1092,7 +1092,7 @@
static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1120,7 +1120,7 @@
static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
jstring src_role, jstring bridge) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1155,7 +1155,7 @@
static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
jstring dstRole) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("connectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1187,7 +1187,7 @@
static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1217,7 +1217,7 @@
static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
jstring path, jstring address,
jstring iface) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanServerDeviceNative");
native_data_t *nat = get_native_data(env, object);
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index f32f0ff..b014006 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -22,24 +22,10 @@
#include <utils/Log.h>
#include <ui/Input.h>
#include "android_view_MotionEvent.h"
+#include "android_util_Binder.h"
#include "android/graphics/Matrix.h"
-#include <math.h>
#include "SkMatrix.h"
-#include "SkScalar.h"
-
-// Number of float items per entry in a DVM sample data array
-#define NUM_SAMPLE_DATA 9
-
-#define SAMPLE_X 0
-#define SAMPLE_Y 1
-#define SAMPLE_PRESSURE 2
-#define SAMPLE_SIZE 3
-#define SAMPLE_TOUCH_MAJOR 4
-#define SAMPLE_TOUCH_MINOR 5
-#define SAMPLE_TOOL_MAJOR 6
-#define SAMPLE_TOOL_MINOR 7
-#define SAMPLE_ORIENTATION 8
namespace android {
@@ -52,35 +38,41 @@
jmethodID obtain;
jmethodID recycle;
- jfieldID mDeviceId;
- jfieldID mSource;
- jfieldID mDownTimeNano;
- jfieldID mAction;
- jfieldID mXOffset;
- jfieldID mYOffset;
- jfieldID mXPrecision;
- jfieldID mYPrecision;
- jfieldID mEdgeFlags;
- jfieldID mMetaState;
- jfieldID mFlags;
- jfieldID mNumPointers;
- jfieldID mNumSamples;
- jfieldID mPointerIdentifiers;
- jfieldID mDataSamples;
- jfieldID mEventTimeNanoSamples;
- jfieldID mLastDataSampleIndex;
- jfieldID mLastEventTimeNanoSampleIndex;
+ jfieldID mNativePtr;
} gMotionEventClassInfo;
+static struct {
+ jclass clazz;
+
+ jfieldID mPackedAxisBits;
+ jfieldID mPackedAxisValues;
+ jfieldID x;
+ jfieldID y;
+ jfieldID pressure;
+ jfieldID size;
+ jfieldID touchMajor;
+ jfieldID touchMinor;
+ jfieldID toolMajor;
+ jfieldID toolMinor;
+ jfieldID orientation;
+} gPointerCoordsClassInfo;
+
// ----------------------------------------------------------------------------
-jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event) {
- jint numPointers = jint(event->getPointerCount());
- jint numHistoricalSamples = jint(event->getHistorySize());
- jint numSamples = numHistoricalSamples + 1;
+static MotionEvent* android_view_MotionEvent_getNativePtr(JNIEnv* env, jobject eventObj) {
+ return reinterpret_cast<MotionEvent*>(
+ env->GetIntField(eventObj, gMotionEventClassInfo.mNativePtr));
+}
+static void android_view_MotionEvent_setNativePtr(JNIEnv* env, jobject eventObj,
+ MotionEvent* event) {
+ env->SetIntField(eventObj, gMotionEventClassInfo.mNativePtr,
+ reinterpret_cast<int>(event));
+}
+
+jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event) {
jobject eventObj = env->CallStaticObjectMethod(gMotionEventClassInfo.clazz,
- gMotionEventClassInfo.obtain, numPointers, numSamples);
+ gMotionEventClassInfo.obtain);
if (env->ExceptionCheck()) {
LOGE("An exception occurred while obtaining a motion event.");
LOGE_EX(env);
@@ -88,168 +80,25 @@
return NULL;
}
- env->SetIntField(eventObj, gMotionEventClassInfo.mDeviceId,
- event->getDeviceId());
- env->SetIntField(eventObj, gMotionEventClassInfo.mSource,
- event->getSource());
- env->SetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano,
- event->getDownTime());
- env->SetIntField(eventObj, gMotionEventClassInfo.mAction,
- event->getAction());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mXOffset,
- event->getXOffset());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mYOffset,
- event->getYOffset());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mXPrecision,
- event->getXPrecision());
- env->SetFloatField(eventObj, gMotionEventClassInfo.mYPrecision,
- event->getYPrecision());
- env->SetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags,
- event->getEdgeFlags());
- env->SetIntField(eventObj, gMotionEventClassInfo.mMetaState,
- event->getMetaState());
- env->SetIntField(eventObj, gMotionEventClassInfo.mFlags,
- event->getFlags());
- env->SetIntField(eventObj, gMotionEventClassInfo.mNumPointers,
- numPointers);
- env->SetIntField(eventObj, gMotionEventClassInfo.mNumSamples,
- numSamples);
- env->SetIntField(eventObj, gMotionEventClassInfo.mLastDataSampleIndex,
- (numSamples - 1) * numPointers * NUM_SAMPLE_DATA);
- env->SetIntField(eventObj, gMotionEventClassInfo.mLastEventTimeNanoSampleIndex,
- numSamples - 1);
-
- jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mPointerIdentifiers));
- jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mDataSamples));
- jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mEventTimeNanoSamples));
-
- jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
- jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
- jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
- eventTimeNanoSampleArray, NULL);
-
- const int32_t* srcPointerIdentifiers = event->getPointerIds();
- jint* destPointerIdentifiers = pointerIdentifiers;
- for (jint i = 0; i < numPointers; i++) {
- *(destPointerIdentifiers++) = *(srcPointerIdentifiers++);
+ MotionEvent* destEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
+ if (!destEvent) {
+ destEvent = new MotionEvent();
+ android_view_MotionEvent_setNativePtr(env, eventObj, destEvent);
}
- const nsecs_t* srcSampleEventTimes = event->getSampleEventTimes();
- jlong* destEventTimeNanoSamples = eventTimeNanoSamples;
- for (jint i = 0; i < numSamples; i++) {
- *(destEventTimeNanoSamples++) = *(srcSampleEventTimes++);
- }
-
- const PointerCoords* srcSamplePointerCoords = event->getSamplePointerCoords();
- jfloat* destDataSamples = dataSamples;
- jint numItems = numSamples * numPointers;
- for (jint i = 0; i < numItems; i++) {
- *(destDataSamples++) = srcSamplePointerCoords->x;
- *(destDataSamples++) = srcSamplePointerCoords->y;
- *(destDataSamples++) = srcSamplePointerCoords->pressure;
- *(destDataSamples++) = srcSamplePointerCoords->size;
- *(destDataSamples++) = srcSamplePointerCoords->touchMajor;
- *(destDataSamples++) = srcSamplePointerCoords->touchMinor;
- *(destDataSamples++) = srcSamplePointerCoords->toolMajor;
- *(destDataSamples++) = srcSamplePointerCoords->toolMinor;
- *(destDataSamples++) = srcSamplePointerCoords->orientation;
- srcSamplePointerCoords += 1;
- }
-
- env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, 0);
- env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
- env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, 0);
-
- env->DeleteLocalRef(pointerIdentifierArray);
- env->DeleteLocalRef(dataSampleArray);
- env->DeleteLocalRef(eventTimeNanoSampleArray);
+ destEvent->copyFrom(event, true);
return eventObj;
}
status_t android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj,
MotionEvent* event) {
- jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId);
- jint source = env->GetIntField(eventObj, gMotionEventClassInfo.mSource);
- jlong downTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano);
- jint action = env->GetIntField(eventObj, gMotionEventClassInfo.mAction);
- jfloat xOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset);
- jfloat yOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset);
- jfloat xPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mXPrecision);
- jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision);
- jint edgeFlags = env->GetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags);
- jint metaState = env->GetIntField(eventObj, gMotionEventClassInfo.mMetaState);
- jint flags = env->GetIntField(eventObj, gMotionEventClassInfo.mFlags);
- jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers);
- jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples);
-
- if (numPointers == 0) {
- LOGE("Malformed MotionEvent: mNumPointers was zero");
- return BAD_VALUE;
- }
- if (numSamples == 0) {
- LOGE("Malformed MotionEvent: mNumSamples was zero");
+ MotionEvent* srcEvent = android_view_MotionEvent_getNativePtr(env, eventObj);
+ if (!srcEvent) {
+ LOGE("MotionEvent was finalized");
return BAD_VALUE;
}
- jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mPointerIdentifiers));
- jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mDataSamples));
- jlongArray eventTimeNanoSampleArray = jlongArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mEventTimeNanoSamples));
-
- jint* pointerIdentifiers = (jint*)env->GetPrimitiveArrayCritical(pointerIdentifierArray, NULL);
- jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
- jlong* eventTimeNanoSamples = (jlong*)env->GetPrimitiveArrayCritical(
- eventTimeNanoSampleArray, NULL);
-
- jfloat* srcDataSamples = dataSamples;
- jlong* srcEventTimeNanoSamples = eventTimeNanoSamples;
-
- jlong sampleEventTime = *(srcEventTimeNanoSamples++);
- PointerCoords samplePointerCoords[MAX_POINTERS];
- for (jint j = 0; j < numPointers; j++) {
- samplePointerCoords[j].x = *(srcDataSamples++);
- samplePointerCoords[j].y = *(srcDataSamples++);
- samplePointerCoords[j].pressure = *(srcDataSamples++);
- samplePointerCoords[j].size = *(srcDataSamples++);
- samplePointerCoords[j].touchMajor = *(srcDataSamples++);
- samplePointerCoords[j].touchMinor = *(srcDataSamples++);
- samplePointerCoords[j].toolMajor = *(srcDataSamples++);
- samplePointerCoords[j].toolMinor = *(srcDataSamples++);
- samplePointerCoords[j].orientation = *(srcDataSamples++);
- }
-
- event->initialize(deviceId, source, action, flags, edgeFlags, metaState,
- xOffset, yOffset, xPrecision, yPrecision, downTimeNano, sampleEventTime,
- numPointers, pointerIdentifiers, samplePointerCoords);
-
- for (jint i = 1; i < numSamples; i++) {
- sampleEventTime = *(srcEventTimeNanoSamples++);
- for (jint j = 0; j < numPointers; j++) {
- samplePointerCoords[j].x = *(srcDataSamples++);
- samplePointerCoords[j].y = *(srcDataSamples++);
- samplePointerCoords[j].pressure = *(srcDataSamples++);
- samplePointerCoords[j].size = *(srcDataSamples++);
- samplePointerCoords[j].touchMajor = *(srcDataSamples++);
- samplePointerCoords[j].touchMinor = *(srcDataSamples++);
- samplePointerCoords[j].toolMajor = *(srcDataSamples++);
- samplePointerCoords[j].toolMinor = *(srcDataSamples++);
- samplePointerCoords[j].orientation = *(srcDataSamples++);
- }
- event->addSample(sampleEventTime, samplePointerCoords);
- }
-
- env->ReleasePrimitiveArrayCritical(eventTimeNanoSampleArray, eventTimeNanoSamples, JNI_ABORT);
- env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, JNI_ABORT);
- env->ReleasePrimitiveArrayCritical(pointerIdentifierArray, pointerIdentifiers, JNI_ABORT);
-
- env->DeleteLocalRef(eventTimeNanoSampleArray);
- env->DeleteLocalRef(dataSampleArray);
- env->DeleteLocalRef(pointerIdentifierArray);
+ event->copyFrom(srcEvent, true);
return OK;
}
@@ -264,85 +113,614 @@
return OK;
}
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
- // Construct and transform a vector oriented at the specified clockwise angle from vertical.
- // Coordinate system: down is increasing Y, right is increasing X.
- SkPoint vector;
- vector.fX = SkFloatToScalar(sinf(angleRadians));
- vector.fY = SkFloatToScalar(- cosf(angleRadians));
- matrix->mapVectors(& vector, 1);
+// ----------------------------------------------------------------------------
- // Derive the transformed vector's clockwise angle from vertical.
- float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(- vector.fY));
- if (result < - M_PI_2) {
- result += M_PI;
- } else if (result > M_PI_2) {
- result -= M_PI;
+static const jint HISTORY_CURRENT = -0x80000000;
+
+static bool validatePointerCount(JNIEnv* env, jint pointerCount) {
+ if (pointerCount < 1) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerCount must be at least 1");
+ return false;
}
- return result;
+ return true;
}
-static void android_view_MotionEvent_nativeTransform(JNIEnv* env,
- jobject eventObj, jobject matrixObj) {
- SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
+static bool validatePointerIdsArray(JNIEnv* env, jintArray pointerIdsArray,
+ size_t pointerCount) {
+ if (!pointerIdsArray) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerIds array must not be null");
+ return false;
+ }
+ size_t length = size_t(env->GetArrayLength(pointerIdsArray));
+ if (length < pointerCount) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerIds array must be large enough to hold all pointers");
+ return false;
+ }
+ return true;
+}
- jfloat oldXOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset);
- jfloat oldYOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset);
- jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers);
- jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples);
- jfloatArray dataSampleArray = jfloatArray(env->GetObjectField(eventObj,
- gMotionEventClassInfo.mDataSamples));
- jfloat* dataSamples = (jfloat*)env->GetPrimitiveArrayCritical(dataSampleArray, NULL);
+static bool validatePointerCoordsObjArray(JNIEnv* env, jobjectArray pointerCoordsObjArray,
+ size_t pointerCount) {
+ if (!pointerCoordsObjArray) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerCoords array must not be null");
+ return false;
+ }
+ size_t length = size_t(env->GetArrayLength(pointerCoordsObjArray));
+ if (length < pointerCount) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerCoords array must be large enough to hold all pointers");
+ return false;
+ }
+ return true;
+}
- // The tricky part of this implementation is to preserve the value of
- // rawX and rawY. So we apply the transformation to the first point
- // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
- SkPoint point;
- jfloat rawX = dataSamples[SAMPLE_X];
- jfloat rawY = dataSamples[SAMPLE_Y];
- matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
- & point);
- jfloat newX = SkScalarToFloat(point.fX);
- jfloat newY = SkScalarToFloat(point.fY);
- jfloat newXOffset = newX - rawX;
- jfloat newYOffset = newY - rawY;
+static bool validatePointerIndex(JNIEnv* env, jint pointerIndex, size_t pointerCount) {
+ if (pointerIndex < 0 || size_t(pointerIndex) >= pointerCount) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerIndex out of range");
+ return false;
+ }
+ return true;
+}
- dataSamples[SAMPLE_ORIENTATION] = transformAngle(matrix, dataSamples[SAMPLE_ORIENTATION]);
+static bool validateHistoryPos(JNIEnv* env, jint historyPos, size_t historySize) {
+ if (historyPos < 0 || size_t(historyPos) >= historySize) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "historyPos out of range");
+ return false;
+ }
+ return true;
+}
- // Apply the transformation to all samples.
- jfloat* currentDataSample = dataSamples;
- jfloat* endDataSample = dataSamples + numPointers * numSamples * NUM_SAMPLE_DATA;
- for (;;) {
- currentDataSample += NUM_SAMPLE_DATA;
- if (currentDataSample == endDataSample) {
- break;
+static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
+ if (!pointerCoordsObj) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "pointerCoords must not be null");
+ return false;
+ }
+ return true;
+}
+
+static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
+ float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
+ outRawPointerCoords->clear();
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
+ env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
+
+ uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
+ if (bits) {
+ jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
+ gPointerCoordsClassInfo.mPackedAxisValues));
+ if (valuesArray) {
+ jfloat* values = static_cast<jfloat*>(
+ env->GetPrimitiveArrayCritical(valuesArray, NULL));
+
+ uint32_t index = 0;
+ do {
+ uint32_t axis = __builtin_ctzll(bits);
+ uint64_t axisBit = 1LL << axis;
+ bits &= ~axisBit;
+ outRawPointerCoords->setAxisValue(axis, values[index++]);
+ } while (bits);
+
+ env->ReleasePrimitiveArrayCritical(valuesArray, values, JNI_ABORT);
+ env->DeleteLocalRef(valuesArray);
+ }
+ }
+}
+
+static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
+ jobject outPointerCoordsObj) {
+ jfloatArray outValuesArray = jfloatArray(env->GetObjectField(outPointerCoordsObj,
+ gPointerCoordsClassInfo.mPackedAxisValues));
+ if (outValuesArray) {
+ uint32_t size = env->GetArrayLength(outValuesArray);
+ if (minSize <= size) {
+ return outValuesArray;
+ }
+ env->DeleteLocalRef(outValuesArray);
+ }
+ uint32_t size = 8;
+ while (size < minSize) {
+ size *= 2;
+ }
+ outValuesArray = env->NewFloatArray(size);
+ env->SetObjectField(outPointerCoordsObj,
+ gPointerCoordsClassInfo.mPackedAxisValues, outValuesArray);
+ return outValuesArray;
+}
+
+static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
+ float xOffset, float yOffset, jobject outPointerCoordsObj) {
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
+ env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+
+ const uint64_t unpackedAxisBits = 0
+ | (1LL << AMOTION_EVENT_AXIS_X)
+ | (1LL << AMOTION_EVENT_AXIS_Y)
+ | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
+ | (1LL << AMOTION_EVENT_AXIS_SIZE)
+ | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
+ | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
+
+ uint64_t outBits = 0;
+ uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
+ if (remainingBits) {
+ uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
+ jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
+ outPointerCoordsObj);
+ if (!outValuesArray) {
+ return; // OOM
}
- jfloat x = currentDataSample[SAMPLE_X] + oldXOffset;
- jfloat y = currentDataSample[SAMPLE_Y] + oldYOffset;
- matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
- currentDataSample[SAMPLE_X] = SkScalarToFloat(point.fX) - newXOffset;
- currentDataSample[SAMPLE_Y] = SkScalarToFloat(point.fY) - newYOffset;
+ jfloat* outValues = static_cast<jfloat*>(env->GetPrimitiveArrayCritical(
+ outValuesArray, NULL));
- currentDataSample[SAMPLE_ORIENTATION] = transformAngle(matrix,
- currentDataSample[SAMPLE_ORIENTATION]);
+ const float* values = rawPointerCoords->values;
+ uint32_t index = 0;
+ do {
+ uint32_t axis = __builtin_ctzll(remainingBits);
+ uint64_t axisBit = 1LL << axis;
+ remainingBits &= ~axisBit;
+ outBits |= axisBit;
+ outValues[index++] = rawPointerCoords->getAxisValue(axis);
+ } while (remainingBits);
+
+ env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
+ env->DeleteLocalRef(outValuesArray);
+ }
+ env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
+}
+
+
+// ----------------------------------------------------------------------------
+
+static jint android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz,
+ jint nativePtr,
+ jint deviceId, jint source, jint action, jint flags, jint edgeFlags, jint metaState,
+ jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision,
+ jlong downTimeNanos, jlong eventTimeNanos,
+ jint pointerCount, jintArray pointerIdsArray, jobjectArray pointerCoordsObjArray) {
+ if (!validatePointerCount(env, pointerCount)
+ || !validatePointerIdsArray(env, pointerIdsArray, pointerCount)
+ || !validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
+ return 0;
}
- env->ReleasePrimitiveArrayCritical(dataSampleArray, dataSamples, 0);
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ if (!event) {
+ event = new MotionEvent();
+ }
- env->SetFloatField(eventObj, gMotionEventClassInfo.mXOffset, newXOffset);
- env->SetFloatField(eventObj, gMotionEventClassInfo.mYOffset, newYOffset);
+ PointerCoords rawPointerCoords[pointerCount];
- env->DeleteLocalRef(dataSampleArray);
+ for (jint i = 0; i < pointerCount; i++) {
+ jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
+ if (!pointerCoordsObj) {
+ jniThrowNullPointerException(env, "pointerCoords");
+ if (!nativePtr) {
+ delete event;
+ }
+ return 0;
+ }
+ pointerCoordsToNative(env, pointerCoordsObj, xOffset, yOffset, &rawPointerCoords[i]);
+ env->DeleteLocalRef(pointerCoordsObj);
+ }
+
+ int* pointerIds = static_cast<int*>(env->GetPrimitiveArrayCritical(pointerIdsArray, NULL));
+
+ event->initialize(deviceId, source, action, flags, edgeFlags, metaState,
+ xOffset, yOffset, xPrecision, yPrecision,
+ downTimeNanos, eventTimeNanos, pointerCount, pointerIds, rawPointerCoords);
+
+ env->ReleasePrimitiveArrayCritical(pointerIdsArray, pointerIds, JNI_ABORT);
+ return reinterpret_cast<jint>(event);
+}
+
+static jint android_view_MotionEvent_nativeCopy(JNIEnv* env, jclass clazz,
+ jint destNativePtr, jint sourceNativePtr, jboolean keepHistory) {
+ MotionEvent* destEvent = reinterpret_cast<MotionEvent*>(destNativePtr);
+ if (!destEvent) {
+ destEvent = new MotionEvent();
+ }
+ MotionEvent* sourceEvent = reinterpret_cast<MotionEvent*>(sourceNativePtr);
+ destEvent->copyFrom(sourceEvent, keepHistory);
+ return reinterpret_cast<jint>(destEvent);
+}
+
+static void android_view_MotionEvent_nativeDispose(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ delete event;
+}
+
+static void android_view_MotionEvent_nativeAddBatch(JNIEnv* env, jclass clazz,
+ jint nativePtr, jlong eventTimeNanos, jobjectArray pointerCoordsObjArray,
+ jint metaState) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ if (!validatePointerCoordsObjArray(env, pointerCoordsObjArray, pointerCount)) {
+ return;
+ }
+
+ PointerCoords rawPointerCoords[pointerCount];
+
+ for (size_t i = 0; i < pointerCount; i++) {
+ jobject pointerCoordsObj = env->GetObjectArrayElement(pointerCoordsObjArray, i);
+ if (!pointerCoordsObj) {
+ jniThrowNullPointerException(env, "pointerCoords");
+ return;
+ }
+ pointerCoordsToNative(env, pointerCoordsObj,
+ event->getXOffset(), event->getYOffset(), &rawPointerCoords[i]);
+ env->DeleteLocalRef(pointerCoordsObj);
+ }
+
+ event->addSample(eventTimeNanos, rawPointerCoords);
+ event->setMetaState(event->getMetaState() | metaState);
+}
+
+static jint android_view_MotionEvent_nativeGetDeviceId(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getDeviceId();
+}
+
+static jint android_view_MotionEvent_nativeGetSource(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getSource();
+}
+
+static void android_view_MotionEvent_nativeSetSource(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint source) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->setSource(source);
+}
+
+static jint android_view_MotionEvent_nativeGetAction(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getAction();
+}
+
+static void android_view_MotionEvent_nativeSetAction(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint action) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->setAction(action);
+}
+
+static jint android_view_MotionEvent_nativeGetFlags(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getFlags();
+}
+
+static jint android_view_MotionEvent_nativeGetEdgeFlags(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getEdgeFlags();
+}
+
+static void android_view_MotionEvent_nativeSetEdgeFlags(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint edgeFlags) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->setEdgeFlags(edgeFlags);
+}
+
+static jint android_view_MotionEvent_nativeGetMetaState(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getMetaState();
+}
+
+static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
+ jint nativePtr, jfloat deltaX, jfloat deltaY) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->offsetLocation(deltaX, deltaY);
+}
+
+static jfloat android_view_MotionEvent_nativeGetXPrecision(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getXPrecision();
+}
+
+static jfloat android_view_MotionEvent_nativeGetYPrecision(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getYPrecision();
+}
+
+static jlong android_view_MotionEvent_nativeGetDownTimeNanos(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getDownTime();
+}
+
+static jint android_view_MotionEvent_nativeGetPointerCount(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return jint(event->getPointerCount());
+}
+
+static jint android_view_MotionEvent_nativeGetPointerId(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint pointerIndex) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
+ return -1;
+ }
+ return event->getPointerId(pointerIndex);
+}
+
+static jint android_view_MotionEvent_nativeFindPointerIndex(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint pointerId) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ for (size_t i = 0; i < pointerCount; i++) {
+ if (event->getPointerId(i) == pointerId) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static jint android_view_MotionEvent_nativeGetHistorySize(JNIEnv* env, jclass clazz,
+ jint nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return jint(event->getHistorySize());
+}
+
+static jlong android_view_MotionEvent_nativeGetEventTimeNanos(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint historyPos) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ if (historyPos == HISTORY_CURRENT) {
+ return event->getEventTime();
+ } else {
+ size_t historySize = event->getHistorySize();
+ if (!validateHistoryPos(env, historyPos, historySize)) {
+ return 0;
+ }
+ return event->getHistoricalEventTime(historyPos);
+ }
+}
+
+static jfloat android_view_MotionEvent_nativeGetRawAxisValue(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
+ return 0;
+ }
+
+ if (historyPos == HISTORY_CURRENT) {
+ return event->getRawAxisValue(axis, pointerIndex);
+ } else {
+ size_t historySize = event->getHistorySize();
+ if (!validateHistoryPos(env, historyPos, historySize)) {
+ return 0;
+ }
+ return event->getHistoricalRawAxisValue(axis, pointerIndex, historyPos);
+ }
+}
+
+static jfloat android_view_MotionEvent_nativeGetAxisValue(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint axis, jint pointerIndex, jint historyPos) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ if (!validatePointerIndex(env, pointerIndex, pointerCount)) {
+ return 0;
+ }
+
+ if (historyPos == HISTORY_CURRENT) {
+ return event->getAxisValue(axis, pointerIndex);
+ } else {
+ size_t historySize = event->getHistorySize();
+ if (!validateHistoryPos(env, historyPos, historySize)) {
+ return 0;
+ }
+ return event->getHistoricalAxisValue(axis, pointerIndex, historyPos);
+ }
+}
+
+static void android_view_MotionEvent_nativeGetPointerCoords(JNIEnv* env, jclass clazz,
+ jint nativePtr, jint pointerIndex, jint historyPos, jobject outPointerCoordsObj) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ size_t pointerCount = event->getPointerCount();
+ if (!validatePointerIndex(env, pointerIndex, pointerCount)
+ || !validatePointerCoords(env, outPointerCoordsObj)) {
+ return;
+ }
+
+ const PointerCoords* rawPointerCoords;
+ if (historyPos == HISTORY_CURRENT) {
+ rawPointerCoords = event->getRawPointerCoords(pointerIndex);
+ } else {
+ size_t historySize = event->getHistorySize();
+ if (!validateHistoryPos(env, historyPos, historySize)) {
+ return;
+ }
+ rawPointerCoords = event->getHistoricalRawPointerCoords(pointerIndex, historyPos);
+ }
+ pointerCoordsFromNative(env, rawPointerCoords, event->getXOffset(), event->getYOffset(),
+ outPointerCoordsObj);
+}
+
+static void android_view_MotionEvent_nativeScale(JNIEnv* env, jclass clazz,
+ jint nativePtr, jfloat scale) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->scale(scale);
+}
+
+static void android_view_MotionEvent_nativeTransform(JNIEnv* env, jclass clazz,
+ jint nativePtr, jobject matrixObj) {
+ SkMatrix* matrix = android_graphics_Matrix_getSkMatrix(env, matrixObj);
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->transform(matrix);
+}
+
+static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass clazz,
+ jint nativePtr, jobject parcelObj) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ if (!event) {
+ event = new MotionEvent();
+ }
+
+ Parcel* parcel = parcelForJavaObject(env, parcelObj);
+
+ status_t status = event->readFromParcel(parcel);
+ if (status) {
+ if (!nativePtr) {
+ delete event;
+ }
+ jniThrowRuntimeException(env, "Failed to read MotionEvent parcel.");
+ return 0;
+ }
+ return reinterpret_cast<jint>(event);
+}
+
+static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass clazz,
+ jint nativePtr, jobject parcelObj) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ Parcel* parcel = parcelForJavaObject(env, parcelObj);
+
+ status_t status = event->writeToParcel(parcel);
+ if (status) {
+ jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
+ }
}
// ----------------------------------------------------------------------------
static JNINativeMethod gMotionEventMethods[] = {
/* name, signature, funcPtr */
+ { "nativeInitialize",
+ "(IIIIIIIFFFFJJI[I[Landroid/view/MotionEvent$PointerCoords;)I",
+ (void*)android_view_MotionEvent_nativeInitialize },
+ { "nativeCopy",
+ "(IIZ)I",
+ (void*)android_view_MotionEvent_nativeCopy },
+ { "nativeDispose",
+ "(I)V",
+ (void*)android_view_MotionEvent_nativeDispose },
+ { "nativeAddBatch",
+ "(IJ[Landroid/view/MotionEvent$PointerCoords;I)V",
+ (void*)android_view_MotionEvent_nativeAddBatch },
+ { "nativeGetDeviceId",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetDeviceId },
+ { "nativeGetSource",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetSource },
+ { "nativeSetSource",
+ "(II)I",
+ (void*)android_view_MotionEvent_nativeSetSource },
+ { "nativeGetAction",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetAction },
+ { "nativeSetAction",
+ "(II)V",
+ (void*)android_view_MotionEvent_nativeSetAction },
+ { "nativeGetFlags",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetFlags },
+ { "nativeGetEdgeFlags",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetEdgeFlags },
+ { "nativeSetEdgeFlags",
+ "(II)V",
+ (void*)android_view_MotionEvent_nativeSetEdgeFlags },
+ { "nativeGetMetaState",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetMetaState },
+ { "nativeOffsetLocation",
+ "(IFF)V",
+ (void*)android_view_MotionEvent_nativeOffsetLocation },
+ { "nativeGetXPrecision",
+ "(I)F",
+ (void*)android_view_MotionEvent_nativeGetXPrecision },
+ { "nativeGetYPrecision",
+ "(I)F",
+ (void*)android_view_MotionEvent_nativeGetYPrecision },
+ { "nativeGetDownTimeNanos",
+ "(I)J",
+ (void*)android_view_MotionEvent_nativeGetDownTimeNanos },
+ { "nativeGetPointerCount",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetPointerCount },
+ { "nativeGetPointerId",
+ "(II)I",
+ (void*)android_view_MotionEvent_nativeGetPointerId },
+ { "nativeFindPointerIndex",
+ "(II)I",
+ (void*)android_view_MotionEvent_nativeFindPointerIndex },
+ { "nativeGetHistorySize",
+ "(I)I",
+ (void*)android_view_MotionEvent_nativeGetHistorySize },
+ { "nativeGetEventTimeNanos",
+ "(II)J",
+ (void*)android_view_MotionEvent_nativeGetEventTimeNanos },
+ { "nativeGetRawAxisValue",
+ "(IIII)F",
+ (void*)android_view_MotionEvent_nativeGetRawAxisValue },
+ { "nativeGetAxisValue",
+ "(IIII)F",
+ (void*)android_view_MotionEvent_nativeGetAxisValue },
+ { "nativeGetPointerCoords",
+ "(IIILandroid/view/MotionEvent$PointerCoords;)V",
+ (void*)android_view_MotionEvent_nativeGetPointerCoords },
+ { "nativeScale",
+ "(IF)V",
+ (void*)android_view_MotionEvent_nativeScale },
{ "nativeTransform",
- "(Landroid/graphics/Matrix;)V",
+ "(ILandroid/graphics/Matrix;)V",
(void*)android_view_MotionEvent_nativeTransform },
+ { "nativeReadFromParcel",
+ "(ILandroid/os/Parcel;)I",
+ (void*)android_view_MotionEvent_nativeReadFromParcel },
+ { "nativeWriteToParcel",
+ "(ILandroid/os/Parcel;)V",
+ (void*)android_view_MotionEvent_nativeWriteToParcel },
};
#define FIND_CLASS(var, className) \
@@ -370,46 +748,36 @@
FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
GET_STATIC_METHOD_ID(gMotionEventClassInfo.obtain, gMotionEventClassInfo.clazz,
- "obtain", "(II)Landroid/view/MotionEvent;");
+ "obtain", "()Landroid/view/MotionEvent;");
GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz,
"recycle", "()V");
+ GET_FIELD_ID(gMotionEventClassInfo.mNativePtr, gMotionEventClassInfo.clazz,
+ "mNativePtr", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mDeviceId, gMotionEventClassInfo.clazz,
- "mDeviceId", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mSource, gMotionEventClassInfo.clazz,
- "mSource", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mDownTimeNano, gMotionEventClassInfo.clazz,
- "mDownTimeNano", "J");
- GET_FIELD_ID(gMotionEventClassInfo.mAction, gMotionEventClassInfo.clazz,
- "mAction", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mXOffset, gMotionEventClassInfo.clazz,
- "mXOffset", "F");
- GET_FIELD_ID(gMotionEventClassInfo.mYOffset, gMotionEventClassInfo.clazz,
- "mYOffset", "F");
- GET_FIELD_ID(gMotionEventClassInfo.mXPrecision, gMotionEventClassInfo.clazz,
- "mXPrecision", "F");
- GET_FIELD_ID(gMotionEventClassInfo.mYPrecision, gMotionEventClassInfo.clazz,
- "mYPrecision", "F");
- GET_FIELD_ID(gMotionEventClassInfo.mEdgeFlags, gMotionEventClassInfo.clazz,
- "mEdgeFlags", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mMetaState, gMotionEventClassInfo.clazz,
- "mMetaState", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mFlags, gMotionEventClassInfo.clazz,
- "mFlags", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mNumPointers, gMotionEventClassInfo.clazz,
- "mNumPointers", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mNumSamples, gMotionEventClassInfo.clazz,
- "mNumSamples", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mPointerIdentifiers, gMotionEventClassInfo.clazz,
- "mPointerIdentifiers", "[I");
- GET_FIELD_ID(gMotionEventClassInfo.mDataSamples, gMotionEventClassInfo.clazz,
- "mDataSamples", "[F");
- GET_FIELD_ID(gMotionEventClassInfo.mEventTimeNanoSamples, gMotionEventClassInfo.clazz,
- "mEventTimeNanoSamples", "[J");
- GET_FIELD_ID(gMotionEventClassInfo.mLastDataSampleIndex, gMotionEventClassInfo.clazz,
- "mLastDataSampleIndex", "I");
- GET_FIELD_ID(gMotionEventClassInfo.mLastEventTimeNanoSampleIndex, gMotionEventClassInfo.clazz,
- "mLastEventTimeNanoSampleIndex", "I");
+ FIND_CLASS(gPointerCoordsClassInfo.clazz, "android/view/MotionEvent$PointerCoords");
+
+ GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, gPointerCoordsClassInfo.clazz,
+ "mPackedAxisBits", "J");
+ GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, gPointerCoordsClassInfo.clazz,
+ "mPackedAxisValues", "[F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.x, gPointerCoordsClassInfo.clazz,
+ "x", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.y, gPointerCoordsClassInfo.clazz,
+ "y", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.pressure, gPointerCoordsClassInfo.clazz,
+ "pressure", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.size, gPointerCoordsClassInfo.clazz,
+ "size", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.touchMajor, gPointerCoordsClassInfo.clazz,
+ "touchMajor", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.touchMinor, gPointerCoordsClassInfo.clazz,
+ "touchMinor", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.toolMajor, gPointerCoordsClassInfo.clazz,
+ "toolMajor", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.toolMinor, gPointerCoordsClassInfo.clazz,
+ "toolMinor", "F");
+ GET_FIELD_ID(gPointerCoordsClassInfo.orientation, gPointerCoordsClassInfo.clazz,
+ "orientation", "F");
return 0;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 2dc0d31..1df6fe5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -82,9 +82,9 @@
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
- <protected-broadcast android:name="android.hardware.action.USB_CONNECTED" />
- <protected-broadcast android:name="android.hardware.action.USB_DISCONNECTED" />
<protected-broadcast android:name="android.hardware.action.USB_STATE" />
+ <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
+ <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
<protected-broadcast android:name="android.hardware.action.USB_DEVICE_ATTACHED" />
<protected-broadcast android:name="android.hardware.action.USB_DEVICE_DETACHED" />
@@ -343,7 +343,7 @@
android:description="@string/permdesc_bluetooth"
android:label="@string/permlab_bluetooth" />
- <!-- Allows applications to directly communicate over NFC -->
+ <!-- Allows applications to perform I/O operations over NFC -->
<permission android:name="android.permission.NFC"
android:permissionGroup="android.permission-group.NETWORK"
android:protectionLevel="dangerous"
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
new file mode 100644
index 0000000..b9435b6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/text_cursor_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
new file mode 100644
index 0000000..477d820
--- /dev/null
+++ b/core/res/res/drawable-hdpi/text_cursor_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
new file mode 100644
index 0000000..b9435b6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_cursor_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png b/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
new file mode 100644
index 0000000..477d820
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_cursor_holo_light.9.png
Binary files differ
diff --git a/core/res/res/raw-es/incognito_mode_start_page.html b/core/res/res/raw-es/incognito_mode_start_page.html
new file mode 100644
index 0000000..43fd37f
--- /dev/null
+++ b/core/res/res/raw-es/incognito_mode_start_page.html
@@ -0,0 +1,26 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
+ <title>Nueva ventana de incógnito</title>
+ </head>
+ <body>
+ <p><strong>Has entrado en el modo "Navegar de incógnito"</strong>. Las páginas
+ que consultes a través de esta ventana no quedarán registradas en el historial del navegador
+ ni en el historial de búsquedas, y tampoco dejarán otros rastros en el equipo (como cookies)
+ una vez cerrada. Aunque sí quedarán almacenados los archivos que descargues y los marcadores
+ que guardes durante la sesión.</p>
+
+ <p><strong>La función "Navegar de incógnito" no afecta al comportamiento de
+ otros usuarios, servidores o programas. Atención con:</strong></p>
+
+ <ul>
+ <li>sitios web que recopilan o comparten información personal,</li>
+ <li>proveedores de servicios de Internet o trabajadores de estas empresas que
+ supervisan las páginas que visita el usuario,</li>
+ <li>software malicioso que realiza un seguimiento de las teclas que pulsa el usuario a
+ cambio de unos emoticones gratuitos,</li>
+ <li>el seguimiento por parte de detectives privados,</li>
+ <li>personas merodeando cerca de tu equipo.</li>
+ </ul>
+ </body>
+</html>
diff --git a/core/res/res/raw/incognito_mode_start_page.html b/core/res/res/raw/incognito_mode_start_page.html
new file mode 100644
index 0000000..5d7a3fb
--- /dev/null
+++ b/core/res/res/raw/incognito_mode_start_page.html
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
+ <title>New incognito window</title>
+ </head>
+ <body>
+ <p><strong>You've gone incognito</strong>. Pages you view in this window
+ won't appear in your browser history or search history, and they won't
+ leave other traces, like cookies, on your device after you close the
+ incognito window. Any files you download or bookmarks you create will be
+ preserved, however.</p>
+
+ <p><strong>Going incognito doesn't affect the behavior of other people,
+ servers, or software. Be wary of:</strong></p>
+
+ <ul>
+ <li>Websites that collect or share information about you</li>
+ <li>Internet service providers or employers that track the pages you visit</li>
+ <li>Malicious software that tracks your keystrokes in exchange for free smileys</li>
+ <li>Surveillance by secret agents</li>
+ <li>People standing behind you</li>
+ </ul>
+ </body>
+</html>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 080d66d..f8c6885 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"وضع الطائرة"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"وضع الطائرة قيد التشغيل"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"وضع الطائرة متوقف"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"+100"</string>
<string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"نظام Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"الخدمات التي تكلفك المال"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لطريقة الإرسال. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"الالتزام بخلفية ما"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"للسماح للمالك بالالتزام بواجهة المستوى العلوي للخلفية. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"الالتزام بخدمة أداة"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الأداة. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"التفاعل مع مشرف الجهاز"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"للسماح للمالك بإرسال الأهداف إلى أحد مشرفي الجهاز. لا يجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"تغيير اتجاه الشاشة"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"للسماح للتطبيق بالتحكم في الضوء الوامض."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"الدخول إلى أجهزة USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"للسماح للتطبيق بالدخول إلى أجهزة USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"تنفيذ بروتوكول MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"لإتاحة الدخول إلى برنامج تشغيل kernel MTP لتنفيذ بروتوكول MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"اختبار الأجهزة"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"للسماح للتطبيق بالتحكم في الأجهزة الطرفية المتنوعة بغرض اختبار الأجهزة."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"اتصال مباشر بأرقام الهواتف"</string>
@@ -466,7 +465,7 @@
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"للسماح لتطبيق ما بالكتابة على وحدة تخزين USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"للسماح لتطبيق ما بالكتابة إلى بطاقة SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تعديل/حذف محتويات وحدة تخزين الوسائط الداخلية"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"للسماح لتطبيق ما بتعديل محتويات وحدة تخزين الوسائط الداخلية."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"للسماح لأحد التطبيقات بتعديل محتويات وحدة تخزين الوسائط الداخلية."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"الدخول إلى نظام ملفات ذاكرة التخزين المؤقت"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"للسماح لتطبيق ما بقراءة نظام ملفات ذاكرة التخزين المؤقت والكتابة به."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"إجراء/تلقي مكالمات عبر الإنترنت"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"تعيين الخادم الوكيل العمومي للجهاز لكي يتم استخدامه أثناء تمكين السياسة. يعين مشرف الجهاز الأول فقط الخادم الوكيل العمومي الفعال."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"تعيين انتهاء صلاحية كلمة المرور"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"التحكم في الوقت المستغرق قبل الحاجة إلى تغيير كلمة مرور شاشة التوقف"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تعيين تشفير التخزين"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"طلب تشفير بيانات التطبيق المخزنة"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"الرئيسية"</item>
<item msgid="869923650527136615">"الجوال"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"العمل"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"غير ذلك"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"أدخل رقم التعريف الشخصي"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"يمكنك اللمس لإدخال كلمة المرور"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"أدخل كلمة المرور لإلغاء التأمين"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"أدخل رقم التعريف الشخصي (PIN) لإلغاء القفل"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"كود PIN غير صحيح!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"كلمة المرور"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"تسجيل الدخول"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"اسم المستخدم غير صحيح أو كلمة المرور غير صحيحة."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"إذا نسيت اسم المستخدم أو كلمة المرور، "\n"فانتقل إلى "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"جارٍ التحقق..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"إلغاء تأمين"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"تشغيل الصوت"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"اختيار تعطيل تصحيح أخطاء USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"تحديد طريقة الإرسال"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"تهيئة طرق الإدخال"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"مشاركة"</string>
<string name="find" msgid="4808270900322985960">"بحث"</string>
<string name="websearch" msgid="4337157977400211589">"بحث الويب"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"طلب الموقع من <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"طلب الموقع"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"مطلوب من <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"نعم"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"لا"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"تم تجاوز حد الحذف."</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"هناك <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> من العناصر المحذوفة بالنسبة إلى <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، في الحساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ما الذي تريد فعله؟"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"حذف هذه العناصر"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"التراجع عن عمليات الحذف"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"عدم تنفيذ أي شيء الآن"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"تم توصيل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"تم فصل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"يمكنك اللمس لإعادة الاتصال بالشبكة الظاهرية الخاصة (VPN)."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"حدد حسابًا."</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"زيادة"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"تناقص"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d1176b8..039ead2 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Самолетен режим"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Самолетният режим е ВКЛЮЧЕН"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Самолетният режим е ИЗКЛЮЧЕН"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Системно от Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Услуги, които ви струват пари"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на метод на въвеждане. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"обвързване с тапет"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на тапет. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обвързване с услуга за приспособления"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за приспособления. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаимодействие с администратор на устройството"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Разрешава на притежателя да изпраща намерения до администратор на устройството. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"промяна на ориентацията на екрана"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Разрешава на приложението да контролира фенерчето."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"достъп до USB устройства"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Разрешава на приложението достъп до USB устройства."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"внедряване на MTP протокол"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Разрешава достъп до MTP драйвера на ядрото за внедряване на протокола MTP през USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"тест на хардуера"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Разрешава на приложението да контролира различни периферни устройства с цел тестване на хардуера."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"директно обаждане до телефонни номера"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"промяна/изтриване на съдържанието на SD картата"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Разрешава на приложението да записва в USB хранилището."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Разрешава на приложението да записва върху SD картата."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"промяна/изтриване на съдържанието на вътрешното мултимедийно хранилище"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"пром./изтр. на съдърж. на вътр. мултим. хранил."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Разрешава на приложението да променя съдържанието на вътрешното мултимедийно хранилище."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"достъп до файловата система на кеша"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Разрешава на приложението да чете и записва във файловата система на кеша."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Задаване на глобалния прокси сървър, който да се използва, когато правилото е активирано. Само първият администратор на устройството задава действителния глобален прокси сървър."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Срок на валидност на паролата"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролирайте след колко време трябва да се променя паролата при заключване на екрана"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Шифроване за хранилището"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Изисква съхраняваните данни за приложенията да бъдат шифровани"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Домашен"</item>
<item msgid="869923650527136615">"Мобилен"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Служебен"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Друг"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Въведете PIN кода"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Докоснете и въведете парола"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Въведете паролата, за да отключите"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Въведете PIN за отключване"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Неправилен PIN код!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Парола"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Вход"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Потребителското име или паролата са невалидни."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Забравили сте своето потребителско име или парола?"\n"Посетете "<b>"google.bg/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Проверява се…"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Отключване"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Включване на звука"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняването на грешки през USB е свързано"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Избиране на метод на въвеждане"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Конфигуриране на въвеждането"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Споделяне"</string>
<string name="find" msgid="4808270900322985960">"Намиране"</string>
<string name="websearch" msgid="4337157977400211589">"Уеб търсене"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Заявка за местоположение от <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Заявка за местоположение"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Заявено от <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Да"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Не"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Лимитът за изтриване бе надхвърлен"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Има <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> изтрити елемента за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, профил <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Какво искате да направите?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Изтриване на елементите."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Отмяна на изтриванията."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Да не се прави нищо засега."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе установена"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе прекъсната"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Докоснете за повторно свързване с VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Избор на профил"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличаване"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Намаляване"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e352fc0..f88f5de 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mode d\'avió"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode d\'avió activat"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode d\'avió desactivat"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"+100"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serveis de pagament"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permet al titular vincular amb la interfície de nivell superior d\'un mètode d\'entrada. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a un empaperat"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permet al titular vincular amb la interfície de nivell superior d\'un empaperat. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincula a un servei de widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de widget. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar amb un administrador del dispositiu"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permet al titular enviar intencions a un administrador del sistema. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"canviar l\'orientació de la pantalla"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permet a l\'aplicació controlar el flaix."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"accedeix a dispositius USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Permet que l\'aplicació accedeixi als dispositius USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementa el protocol MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permet l\'accés al programa de control MTP de kernel per implementar el protocol USB d\'MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"provar el maquinari"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permet a l\'aplicació controlar diversos perifèrics per fer proves de maquinari."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"trucar directament a números de telèfon"</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/suprimir el contingut de les targetes SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permet que una aplicació gravii a l\'emmagatzematge USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permet a una aplicació escriure a la targeta SD."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/suprimeix el contingut d\'emmagatzematge de mitjans interns"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permet que una aplicació modifiqui el contingut de l\'emmagatzematge de mitjans interns."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Canvia/esborra emmagatz. intern"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permet que una aplicació modifiqui el contingut de l\'emmagatzematge multimèdia intern."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accedir al sistema de fitxers de la memòria cau"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permet a una aplicació llegir el sistema de fitxers de la memòria cau i escriure-hi."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"fes/rep trucades per Internet"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Defineix el servidor intermediari global del dispositiu que cal utilitzar mentre la política estigui activada. Només el primer administrador del dispositiu pot definir el servidor intermediari global efectiu."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Defineix la caducitat de la contrasenya"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controla quant de temps abans de la pantalla de bloqueig cal canviar la contrasenya"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Encriptació d’emmagatzematge"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requereix que les dades de l\'aplicació emmagatzemades estiguin encriptades"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Mòbil"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Feina"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altres"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduïu el codi PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Toca per introduir contrasenya"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Introduïu la contrasenya per desbloquejar-lo"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Introdueix el PIN per desbloquejar"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Codi PIN incorrecte."</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contrasenya"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia la sessió"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'usuari o contrasenya no vàlids."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Has oblidat el teu nom d\'usuari o la contrasenya?"\n"Visita "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"S\'està comprovant..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloqueja"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"So activat"</string>
@@ -840,17 +843,17 @@
<string name="volume_ringtone" msgid="6885421406845734650">"Volum del timbre"</string>
<string name="volume_music" msgid="5421651157138628171">"Volum de multimèdia"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"S\'està reproduint a través de Bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"So de trucada silenciós seleccionat"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"To de silenci seleccionat"</string>
<string name="volume_call" msgid="3941680041282788711">"Volum en trucada"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Volum en trucada Bluetooth"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Volum de l\'alarma"</string>
<string name="volume_notification" msgid="2422265656744276715">"Volum de notificació"</string>
<string name="volume_unknown" msgid="1400219669770445902">"Volum"</string>
- <string name="ringtone_default" msgid="3789758980357696936">"So de trucada predeterminat"</string>
- <string name="ringtone_default_with_actual" msgid="8129563480895990372">"So de trucada predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default" msgid="3789758980357696936">"To predeterminat"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"To predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="4440324407807468713">"Silenci"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Sons de trucada"</string>
- <string name="ringtone_unknown" msgid="5477919988701784788">"So de trucada desconegut"</string>
+ <string name="ringtone_unknown" msgid="5477919988701784788">"To desconegut"</string>
<plurals name="wifi_available">
<item quantity="one" msgid="6654123987418168693">"Xarxa Wi-fi disponible"</item>
<item quantity="other" msgid="4192424489168397386">"Xarxes Wi-fi disponibles"</item>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració d\'USB connectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccioneu-ho per desactivar la depuració d\'USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selecció del mètode d\'entrada"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configura mètodes d\'entrada"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Comparteix"</string>
<string name="find" msgid="4808270900322985960">"Cerca"</string>
<string name="websearch" msgid="4337157977400211589">"Cerca al web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Sol·licitud d\'ubicació de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Sol·licitud d\'ubicació"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Sol·licitat per <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sí"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"S\'ha superat el límit de supressions"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Hi ha <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elements suprimits per a <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Què vols fer?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Suprimeix els elements."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Desfés les supressions."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"No facis res de moment."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectada"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconnectada"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Toca per tornar-te a connectar a una VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Selecciona un compte"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementa"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminueix"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 441ad01..a7c74bc 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Vypínání..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet se vypne."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Váš telefon bude vypnut."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Chcete zařízení vypnout?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Žádné nedávno použité aplikace."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Možnosti tabletu"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Režim V letadle"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V letadle je ZAPNUTÝ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V letadle je VYPNUTÝ"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Zpoplatněné služby"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Umožňuje držiteli vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto nastavení nikdy neměly využívat."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vazba na tapetu"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní tapety. Běžné aplikace by toto oprávnění nikdy neměly potřebovat."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"navázat se na službu widgetu"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Umožňuje držiteli navázat se na nejvyšší úroveň služby widgetu. Běžné aplikace by toto oprávnění nikdy neměly potřebovat."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovat se správcem zařízení"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Umožňuje držiteli oprávnění odesílat informace správci zařízení. Běžné aplikace by toto oprávnění nikdy neměly požadovat."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"změna orientace obrazovky"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat pouze výrobce či operátor pro diagnostiku hardwaru."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"povolení či zakázání komponent aplikací"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou pomocí tohoto nastavení vypnout důležité funkce tabletu. Je třeba postupovat opatrně, protože je možné způsobit nepoužitelnost, nekonzistenci či nestabilitu komponent aplikací."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou pomocí tohoto nastavení vypnout důležité funkce tabletu. Je třeba postupovat opatrně, protože je možné způsobit nepoužitelnost, nekonzistenci či nestabilitu komponent aplikací."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou zneužitím tohoto oprávnění vypnout důležité funkce telefonu. S oprávněním je třeba zacházet opatrně, protože je možné způsobit nepoužitelnost, nekonzistenci či nestabilitu komponent aplikací."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"nastavení upřednostňovaných aplikací"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Umožňuje aplikaci změnit vaše upřednostňované aplikace. Toto nastavení může škodlivým aplikacím umožnit nepozorovaně změnit spouštěné aplikace a oklamat vaše existující aplikace tak, aby shromažďovaly vaše soukromá data."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"změna globálních nastavení systému"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Umožňuje aplikaci ovládat kontrolku."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"přístup k zařízením USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Umožní aplikaci přístup k zařízením USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementace protokolu MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Povoluje přístup k ovladači protokolu MTP jádra za účelem implementace protokolu MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testování hardwaru"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Umožňuje aplikaci ovládat různé periferie pro účely testování hardwaru."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"přímé volání na telefonní čísla"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"změna/smazání obsahu karty SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Umožní zápis do úložiště USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Umožní aplikaci zápis na kartu SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Upravit/smazat interní úlož."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Povoluje aplikaci upravovat obsah interního úložiště médií."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"přistupovat do souborového systému mezipaměti"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Umožňuje aplikaci číst a zapisovat do souborového systému mezipaměti."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"uskutečňovat a přijímat internetové hovory"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavit konec platnosti hesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastavit šifrování úložiště"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Požadovat šifrování ukládaných dat"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domů"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Práce"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Jiné"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Zadejte kód PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Dotknete-li se tohoto pole, budete moci zadat heslo"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Zadejte heslo pro odblokování"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Zadejte kód PIN pro odblokování"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Nesprávný kód PIN"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Heslo"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Přihlásit se"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné uživatelské jméno nebo heslo."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Zapomněli jste uživatelské jméno nebo heslo?"\n"Přejděte na stránku "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Probíhá kontrola..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odemknout"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnout zvuk"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Aut.vyp."</string>
<string name="setup_autofill" msgid="8154593408885654044">"Nast. aut. vypl."</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"čtení historie a záložek Prohlížeče"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Umožňuje aplikaci číst všechny navštívené adresy URL a záložky Prohlížeče."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"zápis do historie a záložek Prohlížeče"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Výběr metody zadávání dat"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Nakonfigurovat metody vstupu"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 shoda"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> z <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Hotovo"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Odpojování úložiště USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Odpojování karty SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Mazání úložiště USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Sdílet"</string>
<string name="find" msgid="4808270900322985960">"Najít"</string>
<string name="websearch" msgid="4337157977400211589">"Vyhledat na webu"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Požadavek na informace o poloze od uživatele <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Požadavek na informace o poloze"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Požadavek od uživatele <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ano"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Byl překročen limit mazání."</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Je <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> smazaných položek pro synchronizaci <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> a účet: <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Co chcete udělat?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Smazat položky."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Vrátit mazání zpět."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Neprovádět akci."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je připojena"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je odpojena"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Dotykem se znovu připojíte k síti VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Vybrat účet"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšení"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Snížení"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0242ee9..b29307d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Lukker ned ..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din tabletcomputer slukkes nu."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon slukkes nu."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Vil du slukke?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Der er ingen nye programmer."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Valgmuligheder for tabletcomputeren"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Flytilstand"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flytilstand er TIL"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flytilstand er slået FRA"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjenester, der koster dig penge"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Tillader, at brugeren forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendig til normale programmer."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"forpligt til et tapet"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Tillader, at brugeren forpligter sig til et tapets grænseflade på øverste niveau. Bør aldrig være nødvendig til normale programmer."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"forpligt til en widgettjeneste"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Tillader, at brugeren forpligter sig til en widgettjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige applikationer."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikere med en enhedsadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Tillader brugeren at sende hensigter til en enhedsadministrator. Bør aldrig være nødvendigt for almindelige programmer."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"skift skærmretning"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Tillader, at et program læser og skriver til alle ressourcer, der ejes af diag-gruppen, som f.eks. flier i /dev. Dette kan muligvis påvirke systemets stabilitet og sikkerhed. Dette bør KUN bruges til hardwarespecifikke diagnosticeringer foretaget af producent eller udbyder."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"aktiver eller deaktiver programkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Tillader, at et program ændrer, om en komponent fra et andet program er aktiveret eller ej. Ondsindede programmer kan bruge dette til at deaktivere vigtige funktioner på tabletcomputeren. Denne tilladelse skal anvendes med forsigtighed, da det kan forårsage ubrugelige, inkonsekvente eller ustabile programkomponenter."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Tillader, at et program ændrer, om en komponent fra et andet program er aktiveret eller ej. Ondsindede programmer kan bruge dette til at deaktivere vigtige funktioner på tabletcomputeren. Denne tilladelse skal anvendes med forsigtighed, da det kan forårsage ubrugelige, inkonsekvente eller ustabile programkomponenter."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Tillader, at et program ændrer, om en komponent fra et andet program er aktiveret eller ej. Ondsindede programmer kan bruge dette til at deaktivere vigtige funktioner på telefonen. Denne tilladelse skal anvendes med forsigtighed, da det kan forårsage ubrugelige eller ustabile programkomponenter."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"angiv foretrukne programmer"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Tillader, at et program ændrer dine foretrukne programmer. Dette kan medføre, at ondsindede programmer ændrer kørende programmer i det skjulte og narrer dine eksisterende programmer til at indsamle personlige oplysninger fra dig."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"rediger globale systemindstillinger"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Tillader, at programmet kontrollerer lommelygten."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"adgang til USB-enheder."</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Tillader, at programmet har adgang til USB-enheder."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementere MTP-protokol"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Tillader adgang til kerne-MTP-driveren for at implementere MTB USB-protokollen."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"test hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Tillader, at et program kontrollerer forskellige perifere enheder for at teste hardwaren."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"ring direkte op til telefonnumre"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ret/slet indholdet på SD-kortet"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Tillad skriv til USB-lager."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Tillader, at et program skriver til SD-kortet."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Rediger/slet internt medielagringsindhold"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Tillader, at applikationen ændrer indholdet af det interne medielagringsindhold."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"få adgang til cache-filsystemet"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Tillader, at et program læser og skriver til cache-filsystemet."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"foretage/modtage internetopkald"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angiv enhedens globale proxy, der skal bruges, mens politikken er aktiveret. Kun den første enhedsadministrator angiver den effektive globale proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Indstil udløb for adgangskode"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Angiv kryptering af lager"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Kræv, at gemte programdata krypteres"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbejde"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Andre"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Indtast PIN-kode"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Indtast adgangskode her"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Indtast adgangskode for at låse op"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Indtast pinkode for at låse op"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Forkert PIN-kode!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Adgangskode"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Log ind"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldigt brugernavn eller ugyldig adgangskode."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Har du glemt dit brugernavn eller din adgangskode?"\n"Besøg "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerer ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås op"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd slået til"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"AutoFyld"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Opsætning af AutoFyld"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"læs browserens oversigt og bogmærker"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Tillader, at programmet læser alle de webadresser, browseren har besøgt, og alle browserens bogmærker."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skriv browserens oversigt og bogmærker"</string>
@@ -688,7 +686,7 @@
<string name="save_password_never" msgid="8274330296785855105">"Aldrig"</string>
<string name="open_permission_deny" msgid="5661861460947222274">"Du har ikke tilladelse til at åbne denne side."</string>
<string name="text_copied" msgid="4985729524670131385">"Teksten er kopieret til udklipsholderen."</string>
- <string name="more_item_label" msgid="4650918923083320495">"Flere"</string>
+ <string name="more_item_label" msgid="4650918923083320495">"Mere"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"plads"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"indtast"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
<string name="select_input_method" msgid="6865512749462072765">"Vælg indtastningsmetode"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurer inputmetoder"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 match"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> af <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Udført"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Demonterer USB-lager..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Demonterer SD-kort..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Sletter USB-lager..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Del"</string>
<string name="find" msgid="4808270900322985960">"Find"</string>
<string name="websearch" msgid="4337157977400211589">"Websøgning"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Placeringsanmodning fra <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Placeringsanmodning"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Anmodet om af <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nej"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Grænsen for sletning er overskredet"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Der er <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> slettede elementer for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Hvad vil du gøre?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Slet elementerne."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Fortryd sletningerne."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Gør ikke noget lige nu."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN forbundet"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN afbrudt"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Tryk for at oprette forbindelse til et VPN igen."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Vælg en konto"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Optælling"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Nedtælling"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 87f14c5..3961b9f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -137,9 +137,8 @@
<string name="power_off" msgid="4266614107412865048">"Ausschalten"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Wird heruntergefahren..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ihr Tablet wird heruntergefahren."</string>
- <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ihr Telefon wird heruntergefahren."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon wird heruntergefahren."</string>
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Möchten Sie das Gerät herunterfahren?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Zuletzt verwendet"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Keine zuletzt verwendeten Anwendungen"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet-Optionen"</string>
@@ -147,13 +146,12 @@
<string name="global_action_lock" msgid="2844945191792119712">"Display-Sperre"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Ausschalten"</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Lautlos"</string>
- <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ton ist aus"</string>
- <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ton ist AN"</string>
+ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Ton ist AUS."</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Ton ist AN."</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Flugmodus"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flugmodus ist AN"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flugmodus ist aus"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flugmodus ist AN."</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flugmodus ist AUS."</string>
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Kostenpflichtige Dienste"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Ermöglicht dem Halter, sich an die Oberfläche einer Eingabemethode auf oberster Ebene zu binden. Sollte nie für normale Anwendungen benötigt werden."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"An einen Hintergrund binden"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Ermöglicht dem Halter, sich an die Oberfläche einer Eingabemethode auf oberster Ebene zu binden. Sollte nie für normale Anwendungen benötigt werden."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"An einen Widget-Dienst binden"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Ermöglicht dem Halter, sich an die Oberfläche eines Widget-Dienstes auf oberster Ebene zu binden. Sollte nie für normale Anwendungen benötigt werden."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Interaktion mit einem Geräteadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Ermöglicht dem Halter, Intents an einen Geräteadministrator zu senden. Sollte nie für normale Anwendungen benötigt werden."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"Bildschirmausrichtung ändern"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Ermöglicht einer Anwendung, alle Elemente in der Diagnosegruppe zu lesen und zu bearbeiten, etwa Dateien in \"/dev\". Dies könnte eine potenzielle Gefährdung für die Stabilität und Sicherheit des Systems darstellen und sollte NUR für Hardware-spezifische Diagnosen des Herstellers oder Netzbetreibers verwendet werden."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"Anwendungskomponenten aktivieren oder deaktivieren"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Ermöglicht einer Anwendung, die Komponente einer anderen Anwendung nach Belieben zu aktivieren oder zu deaktivieren. Schädliche Anwendungen können so wichtige Funktionen des Tablets deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die Anwendungskomponenten unbrauchbar, inkonsistent und instabil werden können."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Ermöglicht einer Anwendung, die Komponente einer anderen Anwendung nach Belieben zu aktivieren oder zu deaktivieren. Schädliche Anwendungen können so wichtige Funktionen des Tablets deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die Anwendungskomponenten unbrauchbar, inkonsistent und instabil werden können."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Ermöglicht einer Anwendung, die Komponente einer anderen Anwendung nach Belieben zu aktivieren oder zu deaktivieren. Schädliche Anwendungen können so wichtige Funktionen des Telefons deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die Anwendungskomponenten unbrauchbar, inkonsistent oder instabil werden können."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"bevorzugte Einstellungen festlegen"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Ermöglicht einer Anwendung, Ihre bevorzugten Einstellungen zu ändern. Schädliche Anwendungen können so laufende Anwendungen ohne Ihr Wissen ändern, damit die vorhandenen Anwendungen private Daten von Ihnen sammeln."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"allgemeine Systemeinstellungen ändern"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Ermöglicht der Anwendung, die Lichtanzeige zu steuern."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"auf USB-Geräte zugreifen"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Ermöglicht der Anwendung den Zugriff auf USB-Geräte."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP-Protokoll implementieren"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Erlaubt den Zugriff auf den Kernel-MTP-Treiber zur Implementierung des MTP-USB-Protokolls."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"Hardware testen"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Ermöglicht einer Anwendung, verschiedene Peripherie-Geräte zu Hardware-Testzwecken zu steuern."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"Telefonnummern direkt anrufen"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SD-Karten-Inhalt ändern/löschen"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Ermöglicht der Anwendung Schreiben in USB-Speicher"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Ermöglicht einer Anwendung, auf die SD-Karte zu schreiben"</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Intern. Mediensp. änd./löschen"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Ermöglicht es einer Anwendung, den Inhalt des internen Medienspeichers zu ändern"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"Zugriff auf das Cache-Dateisystem"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Gewährt einer Anwendung Lese- und Schreibzugriff auf das Cache-Dateisystem."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"Internetanrufe tätigen/annehmen"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den globalen Proxy des Geräts zur Verwendung während der Aktivierung der Richtlinie festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ablauf des Passworts festlegen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Speicherverschlüsselung"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Anforderung, dass gespeicherte Anwendungsdaten verschlüsselt werden"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Geschäftlich"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Sonstige"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN-Code eingeben"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Zum Eingeben des Passworts berühren"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Passwort zum Entsperren eingeben"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"PIN zum Entsperren eingeben"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Falscher PIN-Code!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passwort"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Anmelden"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ungültiger Nutzername oder ungültiges Passwort."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Nutzername oder Passwort vergessen?"\n"Besuchen Sie "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Überprüfung..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Entsperren"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ton ein"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"AutoFill"</string>
<string name="setup_autofill" msgid="8154593408885654044">"AutoFill-Setup"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Browserverlauf und Lesezeichen lesen"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Ermöglicht der Anwendung, alle URLs, die mit dem Browser besucht wurden, sowie alle Lesezeichen des Browsers zu lesen."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"Browserverlauf und Lesezeichen schreiben"</string>
@@ -872,14 +870,14 @@
<string name="sms_control_no" msgid="1715320703137199869">"Abbrechen"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Uhrzeit festlegen"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
- <string name="date_time_set" msgid="5777075614321087758">"Einstellen"</string>
+ <string name="date_time_set" msgid="5777075614321087758">"Speichern"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ausblenden"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Alle anzeigen"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-Massenspeicher"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-Verbindung"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Berühren Sie die Schaltfläche unten, wenn Sie Dateien von Ihrem Computer in den USB-Speicher Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Sie haben eine USB-Verbindung mit Ihrem Computer hergestellt. Berühren Sie die Schaltfläche unten, wenn Sie Dateien von Ihrem Computer in den USB-Speicher Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
<string name="usb_storage_message" product="default" msgid="4510858346516069238">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Berühren Sie die Schaltfläche unten, wenn Sie Dateien von Ihrem Computer auf die SD-Karte Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB-Speicher aktivieren"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Bei der Verwendung Ihres USB-Speichers als USB-Massenspeicher ist ein Problem aufgetreten."</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging verbunden"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Auswählen, um USB-Debugging zu deaktivieren."</string>
<string name="select_input_method" msgid="6865512749462072765">"Eingabemethode auswählen"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Eingabemethoden konfigurieren"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 Treffer"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> von <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Fertig"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB-Speicher wird getrennt..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD-Karte wird getrennt..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB-Speicher wird gelöscht..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Freigeben"</string>
<string name="find" msgid="4808270900322985960">"Suchen"</string>
<string name="websearch" msgid="4337157977400211589">"Websuche"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Standortabfrage von <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Standortabfrage"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Angefordert von <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nein"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Löschbegrenzung überschritten"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Für <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, Konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, liegen <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> gelöschte Elemente vor. Was möchten Sie tun?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Elemente löschen"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Löschen rückgängig machen"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Im Moment nichts unternehmen"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> mit VPN verbunden"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> von VPN getrennt"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Zur Wiederherstellung der Verbindung mit einem VPN berühren"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Konto auswählen"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Erhöhen"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Verringern"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6b8db1e..e1c2c39 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Απενεργοποίηση..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Το tablet σας θα απενεργοποιηθεί."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Το τηλέφωνό σας θα απενεργοποιηθεί."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Θέλετε να γίνει τερματισμός λειτουργίας;"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Δεν υπάρχουν πρόσφατες εφαρμογές."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Επιλογές tablet"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Λειτουργία πτήσης"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Η λειτουργία πτήσης είναι ενεργοποιημένη."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Η λειτουργία πτήσης είναι απενεργοποιημένη"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
<string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Υπηρεσίες επί πληρωμή"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας μεθόδου εισόδου. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"δέσμευση σε ταπετσαρία"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας ταπετσαρίας. Δεν είναι απαραίτητο για συνήθεις εφαρμογές."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"δέσμευση σε υπηρεσία γραφικών στοιχείων"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας γραφικών στοιχείων. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"επικοινωνία με έναν διαχειριστή συσκευής"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Επιτρέπει στον κάτοχο την αποστολή στόχων σε έναν διαχειριστή συσκευής. Δεν θα χρειαστεί ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"αλλαγή προσανατολισμού οθόνης"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Επιτρέπει σε μια εφαρμογή την ανάγνωση και την εγγραφή σε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού του κατασκευαστή ή του χειριστή."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Επιτρέπει σε μια εφαρμογή την επιλογή ενεργοποίησης ή μη ενός στοιχείου μιας άλλης εφαρμογής. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να απενεργοποιήσουν σημαντικές δυνατότητες του tablet. Η χορήγηση άδειας πρέπει να γίνεται με προσοχή, καθώς είναι πιθανό τα στοιχεία μιας εφαρμογής να καταστούν ασυνεχή, ασταθή ή να είναι αδύνατον να χρησιμοποιηθούν."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Επιτρέπει σε μια εφαρμογή την επιλογή ενεργοποίησης ή μη ενός στοιχείου μιας άλλης εφαρμογής. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να απενεργοποιήσουν σημαντικές δυνατότητες του tablet. Η χορήγηση άδειας πρέπει να γίνεται με προσοχή, καθώς είναι πιθανό τα στοιχεία μιας εφαρμογής να καταστούν ασυνεχή, ασταθή ή να είναι αδύνατον να χρησιμοποιηθούν."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Επιτρέπει σε μια εφαρμογή την επιλογή ενεργοποίησης ή μη ενός στοιχείου μιας άλλης εφαρμογής. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να απενεργοποιήσουν σημαντικές δυνατότητες του τηλεφώνου. Η χορήγηση αυτής της άδειας πρέπει να γίνεται με προσοχή, καθώς είναι πιθανό τα στοιχεία μιας εφαρμογής να καταστούν ασταθή ή να είναι αδύνατη η χρήση τους."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ορισμός προτιμώμενων εφαρμογών"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Επιτρέπει σε μια εφαρμογή να τροποποιεί τις εφαρμογές που προτιμάτε. Αυτό ενδέχεται να δώσει τη δυνατότητα σε κακόβουλες εφαρμογές να αλλάξουν χωρίς ειδοποίηση τις εφαρμογές που εκτελούνται, \"ξεγελώντας\" τις υπάρχουσες εφαρμογές ώστε να συλλέξουν ιδιωτικά δεδομένα."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"τροποποίηση καθολικών ρυθμίσεων συστήματος"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Επιτρέπει στην εφαρμογή τον έλεγχο του φακού."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"πρόσβαση σε συσκευές USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Επιτρέπει στην εφαρμογή την πρόσβαση σε συσκευές USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"εφαρμογή πρωτοκόλλου MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Επιτρέπει την πρόσβαση στο πρόγραμμα οδήγησης kernel MTP για την εφαρμογή του πρωτοκόλλου MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"δοκιμή υλικού"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Επιτρέπει σε μια εφαρμογή τον έλεγχο διαφόρων περιφερειακών για την εκτέλεση δοκιμών υλικού."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"απευθείας κλήση τηλεφωνικών αριθμών"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"τροποποίηση/διαγραφή περιεχομένων κάρτας SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Επ. εγγρ. εφ. σε απ. χώρο USB"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Επιτρέπει στην εφαρμογή την εγγραφή στην κάρτα SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"τροπ./διαγ. περ. απ. εσ. μνήμ."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Επιτρέπει σε μια εφαρμογή την τροποποίηση περιεχομένων της αποθήκευσης εσωτερικής μνήμης."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"πρόσβαση στο σύστημα αρχείων προσωρινής μνήμης"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Επιτρέπει σε μια εφαρμογή την ανάγνωση και την εγγραφή του συστήματος αρχείων προσωρινής μνήμης."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"πραγματοποίηση/λήψη κλήσεων μέσω Διαδικτύου"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ορίστε τη χρήση του γενικού διακομιστή μεσολάβησης της συσκευής όταν είναι ενεργοποιημένη η πολιτική. Μόνο ο διαχειριστής της πρώτης συσκευής ορίζει τον ισχύοντα γενικό διακομιστή μεσολάβησης."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ορισμός λήξης κωδ. πρόσβασης"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ορισμός κρυπτογρ. αποθ. χώρου"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Να απαιτείται η κρυπτογράφηση των αποθηκευμένων δεδομένων εφαρμογής"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Οικία"</item>
<item msgid="869923650527136615">"Κινητό"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Εργασία"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Άλλο"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Πληκτρολογήστε τον κωδικό αριθμό PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Αγγίξτε για εισαγ. κωδ."</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Εισαγάγετε τον κωδικό πρόσβασης για ξεκλείδωμα"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Εισαγάγετε το PIN για ξεκλείδωμα"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Εσφαλμένος κωδικός αριθμός PIN!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Κωδικός πρόσβασης"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Σύνδεση"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Μη έγκυρο όνομα χρήστη ή κωδικός πρόσβασης."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Ξεχάσετε το όνομα χρήστη ή τον κωδικό πρόσβασής σας;"\n"Επισκεφτείτε τη διεύθυνση "<b>"google.com/accounts/recovery?hl=el-GR"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Έλεγχος..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ξεκλείδωμα"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ενεργοποίηση ήχου"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Αυτ.συμπ"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Ρύθμ. Αυτ. συμπ."</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ανάγνωση ιστορικού και σελιδοδεικτών προγράμματος περιήγησης"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Επιτρέπει στην εφαρμογή την ανάγνωση όλων των διευθύνσεων URL που το πρόγραμμα περιήγησης έχει επισκεφθεί και όλων των σελιδοδεικτών του προγράμματος περιήγησης."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"εγγραφή ιστορικού και σελιδοδεικτών προγράμματος περιήγησης"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Επιλογή μεθόδου εισόδου"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Διαμόρφωση μεθόδων εισαγωγής"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 αποτέλεσμα"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> από <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Ολοκληρώθηκε"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Αποπροσάρτηση αποθηκευτικού χώρου USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Αποπροσάρτηση κάρτας SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Διαγραφή αποθηκευτικού χώρου USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Κοινή χρ."</string>
<string name="find" msgid="4808270900322985960">"Εύρεση"</string>
<string name="websearch" msgid="4337157977400211589">"Αναζήτηση ιστού"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Αίτημα τοποθεσίας από <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Αίτημα τοποθεσίας"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Ζητήθηκε από <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ναι"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Όχι"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Έγινε υπέρβαση του ορίου διαγραφής"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Υπάρχουν <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> διαγραμμένα αντικείμενα για <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, του λογαριασμού <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Τι θέλετε να κάνετε;"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Διαγραφή των αντικειμένων."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Αναίρεση των διαγραφών."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Να μην γίνει καμία ενέργεια τώρα."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> συνδέθηκε"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> αποσυνδέθηκε"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Αγγίξτε για να επανασυνδεθείτε σε ένα VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Επιλογή λογαριασμού"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Αύξηση"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Μείωση"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a981ed6..0ee0e50 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Airplane mode"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Aiplane mode is ON"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Airplane mode is OFF"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services that cost you money"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal applications."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind to wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Allows the holder to bind to the top-level interface of wallpaper. Should never be needed for normal applications."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind to a widget service"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Allows the holder to bind to the top-level interface of a widget service. Should never be needed for normal applications."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interact with device admin"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Allows the holder to send intents to a device administrator. Should never be needed for normal applications."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"change screen orientation"</string>
@@ -286,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Allows an application to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"enable or disable application components"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Allows an application to change whether a component of another application is enabled or not. Malicious applications can use this to disable important tablet capabilities. Care must be used with this permission, as it is possible to get application components into an unusable, inconsistent or unstable state."</string>
- <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Allows an application to change whether a component of another application is enabled or not. Malicious applications can use this to disable important phone capabilities. Care must be used with this permission, as it is possible to get application components into an unusable, inconsistent or unstable state."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Allows an application to change whether a component of another application is enabled or not. Malicious applications can use this to disable important phone capabilities. Care must be used with this permission, as it is possible to render application components into an unusable, inconsistent or unstable condition."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"set preferred applications"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Allows an application to modify your preferred applications. This can allow malicious applications to silently change the applications that are run, spoofing your existing applications to collect private data from you."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modify global system settings"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Allows the application to control the flashlight."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"access USB devices"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Allows the application to access USB devices."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implement MTP protocol"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Allows access to the kernel MTP driver to implement the MTP USB protocol."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"test hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Allows the application to control various peripherals for the purpose of hardware testing."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"directly call phone numbers"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Set the device\'s global proxy to be used while policy is enabled. Only the first device admin sets the effective global proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Set password expiry"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Control how long before lock-screen password needs to be changed"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Set storage encryption"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Require that stored application data be encrypted"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Home"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Enter PIN code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Touch to enter password"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Enter password to unlock"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Enter PIN to unlock"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Incorrect PIN code!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Sign in"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Invalid username or password."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Forgotten your username or password?"\n"Visit "<b>"google.co.uk/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Checking..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Unlock"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sound on"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Select to disable USB debugging."</string>
<string name="select_input_method" msgid="6865512749462072765">"Select input method"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configure input methods"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Share"</string>
<string name="find" msgid="4808270900322985960">"Find"</string>
<string name="websearch" msgid="4337157977400211589">"Web Search"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Location request from <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Location request"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Requested by <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Deletion limit exceeded"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"There are <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> deleted items for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. What would you like to do?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Delete the items."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Undo the deletions."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Do nothing for now."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN connected"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN disconnected"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Touch to reconnect to a VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Select an account"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Increment"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5e6645d..aac30d3 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo avión"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"El modo avión está Encendido"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"El modo avión está Apagado"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicios que te cuestan dinero"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite al propietario vincularse a la interfaz de nivel superior de un método de entrada. Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a un fondo de pantalla"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite al propietario vincularse a la interfaz de nivel superior de un fondo de pantalla. Se debe evitar utilizarlo en aplicaciones normales."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a un servicio de widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permite al propietario vincularse a la interfaz de nivel superior del servicio de widget. Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con un administrador de dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permite que el propietario envíe sus intentos a un administrador de dispositivos. No se necesita para las aplicaciones normales."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"cambiar la orientación de la pantalla"</string>
@@ -286,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Admite una aplicación que lee y escribe a cualquier recurso dentro del grupo de diagnóstico; por ejemplo, archivos con /dev. Esto puede afectar potencialmente la estabilidad y la seguridad del sistema. Debe utilizarlo SÓLO el fabricante o el operador en los diagnósticos específicos del hardware."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"activar o desactivar componentes de la aplicación"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite que una aplicación cambie si se debe activar o no un componente de otra aplicación. Las aplicaciones maliciosas pueden utilizarlo para desactivar funciones importantes del tablet. Se debe tener cuidado con el permiso, ya que es posible que los componentes de la aplicación alcancen un estado inservible, imperfecto e inestable."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que una aplicación cambie si se debe activar o no un componente de otra aplicación. Las aplicaciones maliciosas pueden utilizarlo para desactivar funciones importantes del tablet. Se debe tener cuidado con el permiso, ya que es posible que los componentes de la aplicación alcancen un estado inservible, imperfecto e inestable."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que una aplicación cambie dependiendo de si se debe activar o no un componente de otra aplicación. Las aplicaciones maliciosas pueden utilizarlo para desactivar funciones importantes del teléfono. Se debe tener cuidado con el permiso, ya que es posible que los componentes de la aplicación alcancen un estado inservible, imperfecto o inestable."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Admite una aplicación que modifica tus aplicaciones preferidas. Puede admitir aplicaciones maliciosas que cambien silenciosamente las aplicaciones que se ejecutan e imiten tus aplicaciones existentes para recopilar tus datos privados."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Admite que la aplicación controle la linterna."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"acceder a dispositivos USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Permite que la aplicación acceda a dispositivos USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementar protocolo MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite acceso al driver kernel MTP para implementar el protocolo MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"probar el hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Admite que la aplicación controle diversos periféricos con el fin de probar el hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"llamar directamente a números de teléfono"</string>
@@ -465,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/suprimir el contenido de la tarjeta SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permite que una aplicación escriba en el almacenamiento USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Admite que una aplicación escriba en la tarjeta SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/eliminar los contenidos del almacenamientos de medios internos"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permite que una aplicación modifique los contenidos del almacenamiento interno de medios."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"Acceder al sistema de archivos caché"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permite que una aplicación lea y escriba el sistema de archivos caché."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"realizar o recibir llamadas por Internet"</string>
@@ -489,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Establecer la caducidad de la contraseña"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Establecer la encriptación del almacenamiento"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requiere que los datos almacenados de la aplicación estén encriptados"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -603,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Ingresar el código de PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Toca para ingresar la contraseña"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Ingresar la contraseña para desbloquear"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Ingresa el PIN para desbloquear"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"¡Código de PIN incorrecto!"</string>
@@ -646,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia sesión"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña incorrecta."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"¿Olvidaste tu nombre de usuario o contraseña?"\n"Visita "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Comprobando..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sonido encendido"</string>
@@ -667,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Autocompl."</string>
<string name="setup_autofill" msgid="8154593408885654044">"Conf func Autocompl"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leer historial y marcadores del navegador"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite a la aplicación leer todas las URL que ha visitado el navegador y todos los marcadores del navegador."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"escribir historial y marcadores del navegador"</string>
@@ -809,8 +808,8 @@
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
<string name="loading" msgid="1760724998928255250">"Cargando..."</string>
- <string name="capital_on" msgid="1544682755514494298">"Encendido"</string>
- <string name="capital_off" msgid="6815870386972805832">"APAGADO"</string>
+ <string name="capital_on" msgid="1544682755514494298">"Sí"</string>
+ <string name="capital_off" msgid="6815870386972805832">"No"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar la acción mediante"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de manera predeterminada en esta acción."</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar la predeterminación en Configuración de la página principal > Aplicaciones > Administrar aplicaciones."</string>
@@ -904,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para desactivar la depuración de USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -1002,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Compartir"</string>
<string name="find" msgid="4808270900322985960">"Buscar"</string>
<string name="websearch" msgid="4337157977400211589">"Buscar en la Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitud de ubicación de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitud de ubicación"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sí"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Eliminar el límite excedido"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Existen <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> artículos eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, cuenta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. ¿Qué te gustaría hacer?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Eliminar artículos."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Deshacer eliminaciones."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"No hagas nada por el momento."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN conectados"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN desconectada"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Tocar para volver a conectarse a una VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Seleccionar una cuenta"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decremento"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4f02c4b..51bbd3c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Apagando..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"La tableta se apagará."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"El teléfono se apagará."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"¿Quieres apagar el teléfono?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"No hay aplicaciones recientes"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones de tableta"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo avión"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo avión activado. Desactivar."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo avión desactivado. Activar."</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"+100"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicios por los que tienes que pagar"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite enlazar con la interfaz de nivel superior de un método de introducción de texto. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"enlazar con un fondo de pantalla"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite enlazar con la interfaz de nivel superior de un fondo de pantalla. No debe ser necesario para las aplicaciones normales."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"enlazar con un servicio de widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permite enlazar con la interfaz de nivel superior de un servicio de widget. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactuar con el administrador de un dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permite enviar intentos a un administrador de dispositivos. Este permiso nunca debería ser necesario para las aplicaciones normales."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"cambiar orientación de la pantalla"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Permite que una aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SÓLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"habilitar o inhabilitar componentes de la aplicación"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes de la tableta. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes de la tableta. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que una aplicación cambie si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden utilizar este permiso para inhabilitar funciones importantes del teléfono. Este permiso se debe utilizar con precaución, ya que es posible que los componentes se vuelvan inservibles, inconsistentes o inestables."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permite que una aplicación modifique las aplicaciones preferidas del usuario. De esta forma, las aplicaciones malintencionadas pueden cambiar de forma silenciosa las aplicaciones que se están ejecutando, falsificando las aplicaciones existentes para recopilar datos privados del usuario."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permite que la aplicación controle la función de linterna."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"acceso a dispositivos USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"La aplicación puede acceder a dispositivos USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementar protocolo MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite el acceso al controlador MTP del kernel para implementar el protocolo USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"probar hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permite que la aplicación controle distintos periféricos con fines de prueba del hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"llamar directamente a números de teléfono"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/eliminar contenido de la tarjeta SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permite escribir en USB"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permite que una aplicación escriba en la tarjeta SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"Cambiar/borrar almac interno"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permite que una aplicación modifique el contenido del almacenamiento interno de medios."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"acceder al sistema de archivos almacenado en caché"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permite que una aplicación lea y escriba el sistema de archivos almacenado en caché."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"realizar/recibir llamadas por Internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Definir caducidad contraseña"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Encriptación de almacenamiento"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exige que se encripten los datos de la aplicación almacenados."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Móvil"</item>
@@ -501,7 +499,7 @@
<item msgid="9192514806975898961">"Personalizar"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="8073994352956129127">"Personal"</item>
+ <item msgid="8073994352956129127">"Casa"</item>
<item msgid="7084237356602625604">"Trabajo"</item>
<item msgid="1112044410659011023">"Otra"</item>
<item msgid="2374913952870110618">"Personalizar"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduce el código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Toca para contraseña"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Introducir contraseña para desbloquear"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Introducir PIN para desbloquear"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"El código PIN es incorrecto."</string>
@@ -626,7 +625,7 @@
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Falta la tarjeta SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No se ha insertado ninguna tarjeta SIM en la tableta."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
- <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Solo llamadas de emergencia"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Bloqueada para la red"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con el código PUK."</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Acceder"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña no válido"</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Si has olvidado tu nombre de usuario o tu contraseña,"\n"accede a la página "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Comprobando..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Activar sonido"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Autocompletar"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Config autocomp"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leer información de marcadores y del historial del navegador"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que la aplicación lea todas las URL que ha visitado el navegador y todos sus marcadores."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"escribir en marcadores y en el historial del navegador"</string>
@@ -810,8 +808,8 @@
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
<string name="loading" msgid="1760724998928255250">"Cargando…"</string>
- <string name="capital_on" msgid="1544682755514494298">"Activado"</string>
- <string name="capital_off" msgid="6815870386972805832">"Desconectado"</string>
+ <string name="capital_on" msgid="1544682755514494298">"SÍ"</string>
+ <string name="capital_off" msgid="6815870386972805832">"NO"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar acción utilizando"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de forma predeterminada para esta acción"</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar valores predeterminados en la página de configuración de la pantalla de inicio del teléfono > Aplicaciones > Administrar aplicaciones\"."</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de introducción de texto"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de introducción"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"Una coincidencia"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Listo"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Desactivando almacenamiento USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Desactivando tarjeta SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Borrando almacenamiento USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Compartir"</string>
<string name="find" msgid="4808270900322985960">"Buscar"</string>
<string name="websearch" msgid="4337157977400211589">"Búsqueda web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitud de ubicación de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitud de ubicación"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitud enviada por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sí"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Se ha superado el límite de eliminaciones."</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Hay <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementos eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (cuenta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>). ¿Qué quieres hacer?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Eliminar los elementos"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Deshacer las eliminaciones"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"No hacer nada por ahora"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Toca para volver a conectarte a una red VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Seleccionar una cuenta"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminuir"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 95871a4..fe06a32 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"حالت هواپیما"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"حالت هواپیما روشن است"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"حالت هواپیما خاموش است"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"سرویس های غیر رایگان"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"به نگهدارنده اجازه می دهد به رابط سطح بالای یک روش ورودی متصل شود. هرگز برای برنامه های معمولی مورد نیاز نیست."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"پیوند شده به تصویر زمینه"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"به نگهدارنده اجازه می دهد که به رابط سطح بالای تصویر زمینه متصل شود. هرگز برای برنامه های معمولی مورد نیاز نیست."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"اتصال به یک سرویس ابزارک"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"به صاحب حساب اجازه می دهد که به رابط سطح بالای سرویس ابزارک متصل شود. هرگز برای برنامه های معمولی مورد نیاز نیست."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"تعامل با یک سرپرست دستگاه"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"به نگهدارنده اجازه می دهد مفاد را به یک سرپرست دستگاه ارسال کند. هرگز برای برنامه های معمولی مورد نیاز نیست."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"تغییر جهت صفحه"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"به برنامه کاربردی اجازه می دهد چراغ قوه را کنترل کند."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"دسترسی به دستگاه های USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"به برنامه کاربردی اجازه می دهد به دستگاه های USB دسترسی پیدا کند."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"اعمال پروتکل MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"دسترسی به درایور کرنل MTP جهت اعمال پروتکل MTP USB را اجازه می دهد."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"تست سخت افزار"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"به برنامه کاربردی اجازه می دهد سایر برنامه های جانبی را برای تست سخت افزاری کنترل کند."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"تماس مستقیم با شماره تلفن ها"</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"اصلاح کردن/حذف محتویات کارت SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"به یک برنامه کاربردی اجازه می دهد تا دستگاه USB را بنویسید."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"به یک برنامه کاربردی اجازه می دهد در کارت SD رایت کند."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"اصلاح/حذف محتواهای ذخیره سازی رسانه داخلی"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"به یک برنامه کاربردی برای اصلاح محتواهای حافظه رسانه داخلی اجازه می دهد."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"تغییر/حذف محتواهای حافظه رسانه داخلی"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"به یک برنامه کاربردی برای تغییر محتواهای حافظه رسانه داخلی اجازه می دهد."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"دسترسی به سیستم فایل حافظه پنهان"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"به یک برنامه کاربردی امکان می دهد سیستم فایل حافظه پنهان را بخواند و بنویسد."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"علامتگذاری/دریافت تماس های اینترنتی"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"پروکسی جهانی دستگاه مورد نظر را جهت استفاده هنگام فعال بودن خط مشی تنظیم کنید. فقط اولین سرپرست دستگاه پروکسی جهانی مفید را تنظیم می کند."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"تنظیم زمان انقضای رمز ورود"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"کنترل مدت زمانی که رمز ورود صفحه قفل قبل از تغییر یافتن لازم دارد"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تنظیم رمزگذاری حافظه"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"نیاز به رمزگذاری داده های برنامه کاربردی ذخیره شده دارد"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"خانه"</item>
<item msgid="869923650527136615">"تلفن همراه"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"محل کار"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"سایر موارد"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"کد پین را وارد کنید"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"لمس جهت ورود رمز ورود"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"رمز ورود را برای بازگشایی قفل وارد کنید"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"کد پین را برای بازگشایی قفل وارد کنید"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"پین کد اشتباه است!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"رمز ورود"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ورود به سیستم"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا رمز ورود نامعتبر است."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"نام کاربری و رمز ورود خود را فراموش کردید؟"\n"از "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"در حال بررسی..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"بازگشایی قفل"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"صدا روشن"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"رفع عیب USB متصل شد"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
<string name="select_input_method" msgid="6865512749462072765">"انتخاب روش ورودی"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"پیکربندی روش های ورودی"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"اشتراک گذاری"</string>
<string name="find" msgid="4808270900322985960">"یافتن"</string>
<string name="websearch" msgid="4337157977400211589">"جستجوی وب"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست موقعیت مکانی از <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست موقعیت مکانی"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست شده توسط <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"خیر"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"از حد مجاز حذف فراتر رفت"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می خواهید چه کاری انجام دهید؟"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"موارد را حذف کنید."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"واگرد موارد حذف شده."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"اکنون هیچ کاری انجام نشود."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN وصل شد"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN قطع شد"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"برای اتصال مجدد به VPN لمس کنید."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"انتخاب یک حساب"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"افزایش"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"کاهش"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1392ebb..dc594db 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lentokonetila"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lentokonetila on KÄYTÖSSÄ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lentokonetila on POIS KÄYTÖSTÄ"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Maksulliset palvelut"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Antaa sovelluksen sitoutua syöttötavan ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sido taustakuvaan"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Antaa sovelluksen sitoutua taustakuvan ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sitoudu widget-palveluun"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Antaa sovelluksen sitoutua widget-palvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommunikoi laitteen järjestelmänvalvojan kanssa"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Antaa sovelluksen lähettää kyselyitä laitteen järjestelmänvalvojalle. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"muuta näytön suuntaa"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Antaa sovelluksen hallita lamppua."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"käytä USB-tiloja"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Antaa sovelluksen käyttää USB-tiloja."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"ota käyttöön MTP-protokolla"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Antaa sovelluksen käyttää kernel-MTP-ajuria ja ottaa käyttöön MTP USB-protokollan."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testaa laitteistoa"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Antaa sovelluksen hallita useita liitännäislaitteita laitteistotestaustarkoituksessa."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"soittaa puhelinnumeroihin suoraan"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"muokkaa/poista SD-kortin sisältöä"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Antaa sovelluksen kirjoittaa USB-tallennustilaan."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Antaa sovelluksen kirjoittaa SD-kortille."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"muokkaa/poista säilytystilan sisältöä"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"muokkaa/poista sisäisen säilytystilan sisältöä"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Antaa sovelluksen muokata sisäisen tallennustilan sisältöä."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"käytä välimuistin tiedostojärjestelmää"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Antaa sovelluksen lukea välimuistin tiedostojärjestelmää ja kirjoittaa sinne."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Aseta laitteen yleinen välityspalvelin käyttöön, kun käytäntö on käytössä. Vain ensimmäinen laitteen järjestelmänhallitsija voi asettaa käytettävän yleisen välityspalvelimen."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Aseta salasanan umpeutuminen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Valitse, kuinka pian ruudunlukituksen poiston salasana tulee vaihtaa"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Aseta tallennustilan salaus"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Pakota tallennettujen sovellustietojen salaus"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Puhelinnumero (koti)"</item>
<item msgid="869923650527136615">"Mobiili"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Työ"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Anna PIN-koodi"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Kosketa ja anna salasana"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Poista lukitus antamalla salasana"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Poista lukitus antamalla PIN-koodi"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Virheellinen PIN-koodi!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Salasana"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Kirjaudu sisään"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Virheellinen käyttäjänimi tai salasana."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Unohditko käyttäjänimesi tai salasanasi?"\n"Käy osoitteessa "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Tarkistetaan..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Poista lukitus"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ääni käytössä"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
<string name="select_input_method" msgid="6865512749462072765">"Valitse syöttötapa"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Määritä syöttötavat"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Jaa"</string>
<string name="find" msgid="4808270900322985960">"Etsi"</string>
<string name="websearch" msgid="4337157977400211589">"Verkkohaku"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Sijaintipyyntö käyttäjältä <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Sijaintipyyntö"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Pyytänyt <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Kyllä"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ei"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Poistoraja ylittynyt"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Tilin <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> synkronointityypissä <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> on <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> poistettua kohdetta. Mitä tehdään?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Poista kohteet."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Kumoa poistot."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Älä tee mitään."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys muodostettu"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys katkaistu"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Yhdistä VPN-verkkoon uudelleen koskettamalla."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Valitse tili"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Lisää"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähennä"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 361d193..3e09691 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -71,11 +71,11 @@
<string name="RestrictedOnData" msgid="8653794784690065540">"Le service de données est bloqué."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Le service d\'appel d\'urgence est bloqué."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Le service vocal est bloqué."</string>
- <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Tous les services vocaux sont bloqués."</string>
+ <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Tous les services voix sont bloqués."</string>
<string name="RestrictedOnSms" msgid="8314352327461638897">"Le service SMS est bloqué."</string>
- <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Les services vocaux/de données sont bloqués."</string>
- <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Les services vocaux/SMS sont bloqués."</string>
- <string name="RestrictedOnAll" msgid="2714924667937117304">"Tous les services vocaux/de données/SMS sont bloqués."</string>
+ <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Les services voix/données sont bloqués."</string>
+ <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Les services voix/SMS sont bloqués."</string>
+ <string name="RestrictedOnAll" msgid="2714924667937117304">"Tous les services voix/données/SMS sont bloqués."</string>
<string name="serviceClassVoice" msgid="1258393812335258019">"Voix"</string>
<string name="serviceClassData" msgid="872456782077937893">"Données"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"Télécopie"</string>
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Arrêt en cours..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Votre tablette va s\'éteindre."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Votre téléphone va s\'éteindre."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Voulez-vous éteindre votre mobile ?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Aucune application récente"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Options de la tablette"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mode Avion"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Le mode Avion est activé."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Le mode Avion est désactivé."</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services payants"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permet au support de se connecter à l\'interface de plus haut niveau d\'un mode de saisie. Les applications normales ne devraient jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"Se fixer sur un fond d\'écran"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permet au support de se fixer sur l\'interface de plus haut niveau d\'un fond d\'écran. Les applications normales ne devraient jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associer à un service widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service widget. Les applications standard ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir avec l\'administrateur du périphérique"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permet à l\'application d\'envoyer des intentions à l\'administrateur du périphérique. Les applications standard ne devraient jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"Changement d\'orientation de l\'écran"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Permet à une application de lire et d\'éditer toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers in/dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"Activer ou désactiver des éléments de l\'application"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permet à une application d\'activer ou de désactiver un composant dépendant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver des options importantes de votre tablette. Cette autorisation doit être utilisée avec prudence : elle est susceptible de rendre les composants d\'une application inutilisables, incohérents ou instables."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permet à une application d\'activer ou de désactiver un composant dépendant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver des options importantes de votre tablette. Cette autorisation doit être utilisée avec prudence : elle est susceptible de rendre les composants d\'une application inutilisables, incohérents ou instables."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permet à une application d\'activer ou de désactiver un composant dépendant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver des options importantes de votre téléphone. Cette option doit être utilisée avec prudence : elle est susceptible de rendre les composants d\'une application inutilisables, incohérents ou instables."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"Définition des applications préférées"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permet à une application de modifier vos applications préférées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour modifier discrètement les applications en cours d\'exécution, en imitant vos applications existantes afin de récupérer des données personnelles vous concernant."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"Modification des paramètres généraux du système"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permet à l\'application de contrôler la lampe de poche."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"accéder aux périphériques USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Autorise l\'application à accéder aux périphériques USB"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"mettre en œuvre le protocole MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permet l\'accès au pilote MTP du noyau à des fins de mise en œuvre du protocole USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"Tests du matériel"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permet à l\'application de contrôler différents périphériques à des fins de test matériel."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"Appel direct des numéros de téléphone"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"Modifier/supprimer le contenu de la carte SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Autorise une application à écrire sur la mémoire USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Autorise une application à écrire sur la carte SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./suppr. contenu mémoire interne support"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permet à une application de modifier le contenu de la mémoire de stockage interne du support."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accéder au système de fichiers en cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permet à une application de lire et d\'écrire dans le système de fichiers en cache."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"effectuer/recevoir des appels Internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquez le proxy global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le proxy global utilisé."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Définir date exp. mot de passe"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Définir cryptage du stockage"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exiger que les données d\'application stockées soient cryptées"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domicile"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Professionnelle"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Saisissez le code PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Saisie mot passe"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Saisissez le mot de passe pour procéder au déverrouillage."</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Saisissez le code PIN pour procéder au déverrouillage."</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Le code PIN est incorrect !"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mot de passe"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Se connecter"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nom d\'utilisateur ou mot de passe incorrect."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Vous avez oublié votre nom d\'utilisateur ou votre mot de passe ?"\n"Accédez à la page "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Vérification..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Débloquer"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Son activé"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Saisie auto"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Config. saisie auto"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lire l\'historique et les favoris du navigateur"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Autorise l\'application à lire toutes les URL auxquelles le navigateur a accédé et tous ses favoris."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"écrire dans l\'historique et les favoris du navigateur"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Sélectionner un mode de saisie"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configurer les modes de saisie"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 correspondance"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"OK"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Désinstallation de la mémoire de stockage USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Désinstallation de la carte SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Effacement de la mémoire de stockage USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Partager"</string>
<string name="find" msgid="4808270900322985960">"Rechercher"</string>
<string name="websearch" msgid="4337157977400211589">"Recherche Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Demande de position de la part de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Demande de position"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Demande de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Oui"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Non"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Le nombre maximal de suppressions a été atteint."</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Il existe <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> éléments supprimés pour <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, pour le compte <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Que souhaitez-vous faire ?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Supprimer les éléments"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Annuler les suppressions"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Ne rien faire pour l\'instant"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connecté"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> déconnecté"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Appuyez ici pour vous reconnecter à un VPN"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Sélectionner un compte"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Augmenter"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuer"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index befb526..b9e2753 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Način rada u zrakoplovu"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uključen je način rada u zrakoplovu"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Isključen je način rada u zrakoplovu"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Usluge koje se plaćaju"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Nositelju omogućuje da se veže uz sučelje najviše razine za metodu unosa. Nikad ne bi trebalo koristiti za uobičajene aplikacije."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"povezano s pozadinskom slikom"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Nositelju omogućuje da se veže uz sučelje najviše razine za pozadinsku sliku. Nikad ne bi trebalo koristiti za uobičajene aplikacije."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vezanje na uslugu widgeta"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge widgeta. Nije potrebno za uobičajene aplikacije."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s administratorom uređaja"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Nositelju omogućuje slanje namjera administratoru uređaja. Nikad ne bi trebalo koristiti za uobičajene aplikacije."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"promjena orijentacije zaslona"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Aplikaciji omogućuje nadzor nad bljeskalicom."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"pristupi USB uređajima"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Omogućuje aplikaciji pristup USB uređajima."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"Primjena MTP protokola"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Omogućuje pristup upravljačkom programu jezgre MTP-a radi implementacije MTP USB protokola."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testiranje hardvera"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Aplikacijama omogućuje nadzor nad raznim vanjskim jedinicama u svrhu hardverskog testiranja."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"izravno pozivanje telefonskog broja"</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"izmjena/brisanje sadržaja SD kartice"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Omog. pisanje na USB memoriju."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Aplikaciji omogućuje pisanje na SD karticu."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"izmijeni/briši sadržaje unutarnjih medija pohrane"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Omogućuje aplikaciji izmjenu sadržaja pohrane unutarnjih medija."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"izmijeni/izbriši sadržaj pohranjen na internim medijima"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Aplikaciji omogućuje izmjenu sadržaja pohranjenog na internim medijima."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"pristup sustavu datoteka predmemorije"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Aplikaciji omogućuje čitanje i pisanje u sustav datoteka predmemorije."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"zovi/primaj internetske pozive"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Postavi globalni proxy uređaja za upotrebu dok su pravila omogućena. Samo prvi administrator uređaja postavlja djelotvoran globalni proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Postavi istek zaporke"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Nadzirite za koliko vremena zaporka za zaključani zaslon treba biti promijenjena"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Postavi enkripciju za pohranu"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Zahtijevaj da pohranjeni podaci aplikacije budu kriptirani"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Početna"</item>
<item msgid="869923650527136615">"Mobilni"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Posao"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Unesite PIN kôd"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Dodir. za unos zaporke"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Unesite zaporku za otključavanje"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Unesite PIN za otključavanje"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Netočan PIN kôd!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Zaporka"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prijava"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nevažeće korisničko ime ili zaporka."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Zaboravili ste korisničko ime ili zaporku?"\n"Posjetite "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Provjera..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Otključaj"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zvuk je uključen"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje programske pogreške USB-a"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
<string name="select_input_method" msgid="6865512749462072765">"Odaberite način unosa"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfiguriraj načine ulaza"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Dijeli"</string>
<string name="find" msgid="4808270900322985960">"Pronađi"</string>
<string name="websearch" msgid="4337157977400211589">"Pretraž. weba"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Zahtjev za lokaciju koji upućuje <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za lokaciju"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Zatražio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Prekoračeno je ograničenje za brisanje"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Postoji ovoliko izbrisanih stavki: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> za sinkronizaciju <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, račun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Što želite učiniti?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Izbriši ove stavke."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Poništi brisanja."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Za sad nemoj ništa učiniti."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN priključen"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN je isključen"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Dotaknite za ponovno povezivanje s VPN-om."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Odaberite račun"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Povećaj"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Smanji"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0ee1bbc..a4ee0cb 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Repülőgép üzemmód"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Repülőgép üzemmód bekapcsolva"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Repülőgép üzemmód kikapcsolva"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Fizetős szolgáltatások"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Lehetővé teszi a használó számára a beviteli módszer legfelső szintű kezelőfelületéhez való csatlakozást. A normál alkalmazások soha nem használják ezt."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"összekapcsolás háttérképpel"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Lehetővé teszi a használó számára, hogy csatlakozzon egy háttérkép legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"csatlakozás modulszolgáltatáshoz"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Lehetővé teszi a használó számára, hogy csatlakozzon egy modulszolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"az eszközkezelő használata"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Lehetővé teszi a használó számára, hogy célokat küldjön egy eszközkezelőnek. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"képernyő irányának módosítása"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Lehetővé teszi az alkalmazás számára a vaku vezérlését."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"USB-eszközök elérése"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Lehetővé teszi az alkalmazások számára az USB-eszközök elérését."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP-protokoll megvalósítása"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Hozzáférést biztosít a kernel MTP illesztőprogramjához az MTP USB-protokoll megvalósításának céljából."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"hardver tesztelése"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Lehetővé teszi az alkalmazás számára különböző perifériák vezérlését hardvertesztelés céljából."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"telefonszámok közvetlen hívása"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"az SD-kártya tartalmának módosítása és törlése"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Lehetővé teszi az alkalmazások számára, hogy írjanak az USB-tárra."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Lehetővé teszi egy alkalmazás számára, hogy írjon az SD-kártyára."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"a belső médiatároló tartalmának módosítása és törlése"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"belső tár tartalmának módosítása/törlése"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Lehetővé teszi az alkalmazások számára, hogy módosítsák a belső tárhely tartalmát."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"hozzáférés a gyorsítótár fájlrendszeréhez"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Lehetővé teszi egy alkalmazás számára a gyorsítótár fájlrendszerének olvasását és írását."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Az eszköz globális proxyja lesz használatban, amíg az irányelv engedélyezve van. Csak az eszköz első rendszergazdája állíthatja be a tényleges globális proxyt."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Jelszó lejáratának beállítása"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Azt vezérli, mennyi időnként kell módosítani a képernyőt zároló jelszót"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Tárhelytitkosítás beállítása"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Megköveteli a tárolt alkalmazásadatok titkosítását"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Otthoni"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Munkahely"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Egyéb"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Adja meg a PIN-kódot"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Érintse meg jelszóhoz"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"A feloldáshoz írja be a jelszót"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Feloldáshoz írja be a PIN kódot"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Helytelen PIN-kód."</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Jelszó"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Bejelentkezés"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Érvénytelen felhasználónév vagy jelszó."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Elfelejtette a felhasználónevét vagy jelszavát?"\n"Keresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet"</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Ellenőrzés..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Feloldás"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Hang bekapcsolása"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
<string name="select_input_method" msgid="6865512749462072765">"Válassza ki a beviteli módszert"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Beviteli módok konfigurálása"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Megosztás"</string>
<string name="find" msgid="4808270900322985960">"Keresés"</string>
<string name="websearch" msgid="4337157977400211589">"Webes keresés"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Helykérelem a következőtől: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Helykérelem"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Igénylő <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Igen"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nem"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"A szinkronizálás elérte a törlésre vonatkozó korlátot"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> törölt elem van a(z) <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> szinkronizálásánál, a(z) <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> fiókban. Mit kíván tenni?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Az elemek törlése."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Törlés visszavonása."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Most nem."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Kapcsolódva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózathoz"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Bontotta a kapcsolatot a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózattal"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Érintse meg az újracsatlakozáshoz."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Fiók kiválasztása"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Növelés"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Csökkentés"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 304ef90..b6d0d43 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mode pesawat"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Mode pesawat HIDUP"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Mode pesawat MATI"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Layanan berbayar"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi pada suatu metode masukan. Tidak diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"mengikat ke wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu wallpaper. Tidak diperlukan untuk aplikasi normal."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"mengikat ke layanan widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan widget. Tidak diperlukan untuk aplikasi normal."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan admin perangkat"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Mengizinkan pemegang mengirimkan tujuan kepada administrator perangkat. Tidak diperlukan untuk aplikasi normal."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ubah orientasi layar"</string>
@@ -286,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Mengizinkan aplikasi membaca dan menulis ke sumber daya yang dimiliki oleh grup diag; misalnya, berkas dalam /dev. Ini berisiko mempengaruhi kestabilan dan keamanan sistem. Ini sebaiknya HANYA digunakan untuk diagnostik khusus perangkat keras oleh pabrik atau operator."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"aktifkan atau nonaktifkan komponen aplikasi"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Izinkan aplikasi mengubah apakah komponen aplikasi lain diaktifkan atau tidak. Aplikasi berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan tablet penting. Hati-hatilah saat menggunakan izin ini, karena komponen aplikasi tidak akan dapat digunakan, tidak konsisten, atau tidak stabil."</string>
- <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Izinkan aplikasi mengubah apakah komponen aplikasi lain diaktifkan atau tidak. Aplikasi berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan ponsel penting. Hati-hatilah saat menggunakan izin ini, karena komponen aplikasi tidak akan dapat digunakan, tidak konsisten, atau tidak stabil."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Izinkan aplikasi untuk mengubah apakah komponen aplikasi lain diaktifkan atau tidak. Aplikasi jahat dapat menggunakan ini untuk menonaktifkan kemampuan ponsel yang penting. Hati-hatilah saat menggunakan izin ini karena berpeluang menyebabkan komponen aplikasi menjadi tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"atur aplikasi yang disukai"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Mengizinkan aplikasi memodifikasi aplikasi yang dipilih. Ini dapat dimanfaatkan aplikasi hasad untuk diam-diam mengubah aplikasi yang sedang berjalan, spoofing aplikasi yang ada untuk mengumpulkan data pribadi dari Anda."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Mengizinkan aplikasi mengontrol lampu senter."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"akses perangkat USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Mengizinkan aplikasi untuk perangkat USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementasikan protokol MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Izinkan akses pada driver MTP kernel untuk mengimplementasikan protokol USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"uji perangkat keras"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Mengizinkan aplikasi mengontrol berbagai perangkat periferal untuk tujuan menguji perangkat keras."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"panggil nomor telepon secara langsung"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setel proxy global perangkat yang akandigunakan ketika kebijakan diaktifkan. Hanya admin perangkat pertama yang menyetel procy global yang berlaku."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Setel kedaluwarsa sandi"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrol berapa lama sebelum sandi penguncian layar perlu diubah"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setel enkripsi penyimpanan"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Mengharuskan data aplikasi yang disimpan untuk dienkripsi"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Rumah"</item>
<item msgid="869923650527136615">"Seluler"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerjaan"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Lainnya"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Masukkan kode PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Sentuh untuk memasukkan sandi"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Masukkan sandi untuk membuka"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Masukkan PIN untuk membuka kunci"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Kode PIN salah!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Sandi"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Masuk"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nama pengguna atau sandi tidak valid."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Lupa nama pengguna atau sandi Anda?"\n"Kunjungi "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Memeriksa..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Buka kunci"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Suara hidup"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pilih metode masukan"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurasikan metode masukan"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Bagikan"</string>
<string name="find" msgid="4808270900322985960">"Temukan"</string>
<string name="websearch" msgid="4337157977400211589">"Penelusuran Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Permintaan lokasi dari <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Permintaan lokasi"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Diminta oleh <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ya"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Tidak"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Penghapusan melebihi batas"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Terdapat <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> item yang dihapus untuk <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, akun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Apakah yang ingin Anda lakukan?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Hapus item."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Urungkan penghapusan."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Jangan lakukan apa pun untuk saat ini."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN tersambung"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN terputus"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Sentuh untuk terhubung kembali ke VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Pilih akun"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Penambahan"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Pengurangan"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 282d375..047f9b8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Spegnimento..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Il tablet verrà spento."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Il telefono verrà spento."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Spegnere?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Nessuna applicazione recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opzioni tablet"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modalità aereo"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modalità aereo attiva"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modalità aereo non attiva"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servizi che prevedono un costo"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Consente l\'associazione all\'interfaccia principale di un metodo di inserimento. Non dovrebbe essere mai necessario per le normali applicazioni."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"associazione a sfondo"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Consente l\'associazione di uno sfondo all\'interfaccia principale. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associazione a un servizio widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Consente l\'associazione all\'interfaccia principale di un servizio widget. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interazione con un amministratore dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Consente l\'invio di intent a un amministratore del dispositivo. L\'autorizzazione non deve mai essere necessaria per le normali applicazioni."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"modifica orientamento dello schermo"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Consente a un\'applicazione di leggere le risorse del gruppo diag e scrivere a esse, per esempio i file in /dev. Questa capacità potrebbe influire sulla stabilità e sicurezza del sistema. Dovrebbe essere utilizzata SOLTANTO per diagnostiche specifiche dell\'hardware effettuate dal produttore o dall\'operatore."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"attivazione/disattivazione componenti applicazioni"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Consente a un\'applicazione di attivare o disattivare un componente di un\'altra applicazione. Le applicazioni dannose possono sfruttare questa possibilità per disattivare importanti funzionalità del tablet. Prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Consente a un\'applicazione di attivare o disattivare un componente di un\'altra applicazione. Le applicazioni dannose possono sfruttare questa possibilità per disattivare importanti funzionalità del tablet. Prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Consente a un\'applicazione di attivare o disattivare un componente di un\'altra applicazione. Le applicazioni dannose possono sfruttare questa possibilità per disattivare importanti funzionalità del telefono. Prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"impostazione applicazioni preferite"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Consente la modifica da parte di un\'applicazione delle applicazioni preferite. Le applicazioni dannose potrebbero essere in grado di modificare automaticamente le applicazioni in esecuzione, effettuando lo spoofing delle applicazioni esistenti per raccogliere dati riservati."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modifica impostazioni di sistema globali"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Consente all\'applicazione di controllare il flash."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"accesso a dispositivi USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Consente all\'applicazione di accedere ai dispositivi USB"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementa protocollo MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Consente di accedere al driver MTP del kernel per implementare il protocollo USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"esecuzione test hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Consente all\'applicazione di controllare varie periferiche per il test dell\'hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"chiamata diretta n. telefono"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificare/eliminare i contenuti della scheda SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Consente di scrivere nell\'archivio USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Consente a un\'applicazione di scrivere sulla scheda SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modifica/eliminaz. contenuti archivio media int."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Consente a un\'applicazione di modificare i contenuti dell\'archivio media interno."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesso al filesystem nella cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Consente a un\'applicazione di leggere e scrivere il filesystem nella cache."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"effettuazione/ricezione chiamate Internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Imposta il proxy globale del dispositivo in modo da utilizzarlo mentre la norma è attiva. Il proxy globale effettivo è impostabile solo dal primo amministratore del dispositivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Imposta scadenza password"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Stabilisci la scadenza della password di blocco dello schermo"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Imposta crittografia archivio"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Richiede la crittografia dei dati applicazione memorizzati"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Cellulare"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Lavoro"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altro"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Inserisci il PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Tocca e inserisci password"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Inserisci password per sbloccare"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Inserisci PIN per sbloccare"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Codice PIN errato."</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Accedi"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Password o nome utente non valido."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Hai dimenticato il nome utente o la password?"\n"Visita "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controllo in corso..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Sblocca"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Audio attivato"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Compl. auto"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Compil. automatica"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lettura cronologia e segnalibri del browser"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Consente all\'applicazione di leggere tutti gli URL visitati e tutti i segnalibri del browser."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"creazione cronologia e segnalibri del browser"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleziona metodo di inserimento"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configura metodi di input"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 corrispondenza"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> di <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Fine"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Smontaggio dell\'archivio USB in corso..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Smontaggio scheda SD in corso..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Cancellazione dell\'archivio USB in corso..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Condividi"</string>
<string name="find" msgid="4808270900322985960">"Trova"</string>
<string name="websearch" msgid="4337157977400211589">"Ricerca Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Richiesta posizione da <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Richiesta posizione"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Richiesto da <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sì"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limite di eliminazioni superato"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Esistono <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementi eliminati per <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Cosa vuoi fare?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Elimina gli elementi."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Annulla le eliminazioni."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Non fare nulla per ora."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> collegata"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> scollegata"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Tocca per riconnetterti a una rete VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Seleziona un account"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumenta"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuisci"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index ea48002..f268fbf 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"מצב טיסה"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"מצב טיסה מופעל"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"מצב טיסה כבוי"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
<string name="android_system_label" msgid="6577375335728551336">"מערכת Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"שירותים שעולים לך כסף"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"מאפשר למחזיק להכפיף לממשק ברמה עליונה של שיטת קלט. לא אמור להידרש לעולם ביישומים רגילים."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"קשור לטפט"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"מאפשר למחזיק לקשור לממשק ברמה עליונה של טפט. לא אמור להידרש לעולם ביישומים רגילים."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"הכפפה לשירות Widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"מאפשר למחזיק להכפיף לממשק ברמה עליונה של שירות Widget. יישומים רגילים לעולם לא יזדקקו לו."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"קיים אינטראקציה עם מנהל מכשיר"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"מאפשר למשתמש לשלוח כוונות למנהל התקן. לא אמור להידרש לעולם ביישומים רגילים."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"שנה את כיוון המסך"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"מאפשר ליישום לשלוט בפנס."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"גישה להתקני USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"מאפשר ליישום גישה להתקני USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"יישם פרוטוקול MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"מאפשר גישה למנהל התקן MTP של הליבה כדי ליישם פרוטוקול USB של MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"בדוק חומרה"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"מאפשר ליישום לשלוט בציוד היקפי מסוגים שונים לצורך בדיקת חומרה."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"התקשר ישירות למספרי טלפון"</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"שנה/מחק את התוכן של כרטיס SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"מאפשר ליישום לכתוב לאמצעי אחסון מסוג USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"מאפשר ליישום לכתובת לכרטיס ה-SD."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תכנים של מדיית אחסון פנימית"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"מאפשר ליישום לשנות את התכנים של אחסון המדיה הפנימי."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"שנה/מחק תוכן של מדיית אחסון פנימית"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"מאפשר ליישום לשנות את התוכן של מדיית האחסון הפנימית."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"גישה למערכת הקבצים של הקובץ השמור"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"מאפשר ליישום לקרוא ולכתוב במערכת הקבצים של הקובץ השמור."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"בצע/קבל שיחות אינטרנט"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"הגדר את שרת proxy הגלובלי של ההתקן לשימוש כאשר המדיניות מופעלת. רק מנהל ההתקן הראשון מגדיר את שרת ה-proxy הגלובלי הפעיל."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"הגדר תפוגת תוקף של סיסמה"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"שלוט בפרק הזמן הדרוש לשינוי הסיסמה של נעילת המסך"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"הגדר הצפנת אחסון"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"דורש שנתוני היישום המאוחסנים יהיו מוצפנים"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"דף הבית"</item>
<item msgid="869923650527136615">"נייד"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"עבודה"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"אחר"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"הזן קוד PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"גע כדי להזין סיסמה"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"הזן סיסמה לביטול הנעילה"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"הזן PIN לביטול נעילה"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"קוד PIN שגוי!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"סיסמה"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"כניסה"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"שם משתמש או סיסמה לא חוקיים."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"שכחת את שם המשתמש או הסיסמה?"\n"בקר בכתובת "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"בודק..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"בטל נעילה"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"קול פועל"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"ניקוי באגים של USB מחובר"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"בחר כדי להשבית ניקוי באגים ב-USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"בחר שיטת קלט"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"הגדר שיטות קלט"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZאבגדהוזחטיכלמנסעפצקרשת"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789אבגדהוזחטיכלמנסעפצקרשת"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"שתף"</string>
<string name="find" msgid="4808270900322985960">"חפש"</string>
<string name="websearch" msgid="4337157977400211589">"חיפוש Google"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"בקשת מיקום מ-<xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"בקשת מיקום"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"מבוקש על ידי <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"כן"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"לא"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"חרגת ממגבלת המחיקה"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"יש <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> פריטים שנמחקו עבור <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, חשבון <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. מה ברצונך לעשות?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"מחק את הפריטים."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"בטל את המחיקות."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"אל תעשה דבר בינתיים."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> מחובר"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> נותק"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"גע כדי להתחבר שוב ל-VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"בחר חשבון"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"הוספה"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"הפחתה"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6df5f3d..ce6d13d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"シャットダウン中..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"タブレットの電源をOFFにします。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"携帯電話の電源を切ります。"</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"シャットダウンしますか?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"最近使ったアプリケーションはありません。"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"タブレットオプション"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"機内モード"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"機内モードON"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"機内モードOFF"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100超"</string>
<string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
<string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"料金の発生するサービス"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"入力方法のトップレベルインターフェースに関連付けることを所有者に許可します。通常のアプリケーションにはまったく必要ありません。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"壁紙にバインド"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"壁紙のトップレベルインターフェースへのバインドを所有者に許可します。通常のアプリケーションでは不要です。"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ウィジェットサービスにバインド"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"ウィジェットサービスのトップレベルインターフェースへのバインドを所有者に許可します。通常のアプリケーションでは不要です。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"デバイス管理者との通信"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"デバイス管理者へのintentの送信を所有者に許可します。通常のアプリケーションでは不要です。"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"画面の向きの変更"</string>
@@ -284,10 +284,10 @@
<string name="permdesc_readLogs" product="tablet" msgid="4077356893924755294">"システムの各種ログファイルの読み取りをアプリケーションに許可します。許可するとタブレットの使用状況に関する全般的な情報が読み取られます。この情報には個人情報や機密情報が含まれる場合があります。"</string>
<string name="permdesc_readLogs" product="default" msgid="8896449437464867766">"システムの各種ログファイルの読み取りをアプリケーションに許可します。許可すると端末の使用状況に関する全般的な情報が読み取られます。この情報には個人情報や機密情報が含まれる場合があります。"</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
- <string name="permdesc_diagnostic" msgid="3121238373951637049">"diagグループが所有するリソース(例:/dev内のファイル)への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/オペレーターによるハードウェア固有の診断以外には使用しないでください。"</string>
+ <string name="permdesc_diagnostic" msgid="3121238373951637049">"diagグループが所有するリソース(例:/dev内のファイル)への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"アプリケーションのコンポーネントを有効/無効にする"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。この許可を悪意のあるアプリケーションに利用されると、タブレットの重要な機能が無効にされる恐れがあります。アプリケーションコンポーネントが利用できなくなる、整合性が取れなくなる、または不安定な状態になる恐れがあるので許可には注意が必要です。"</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。この許可を悪意のあるアプリケーションに利用されると、タブレットの重要な機能が無効にされる恐れがあります。アプリケーションコンポーネントが利用できなくなる、整合性が取れなくなる、または不安定な状態になる恐れがあるので許可には注意が必要です。"</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。この許可を悪意のあるアプリケーションに利用されると、端末の重要な機能が無効にされる恐れがあります。アプリケーションコンポーネントが利用できなくなる、整合性が取れなくなる、または不安定な状態になる恐れがあるので許可には注意が必要です。"</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"優先アプリケーションの設定"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"優先アプリケーションを変更することをアプリケーションに許可します。悪意のあるアプリケーションが実行中のアプリケーションを密かに変更し、既存のアプリケーションになりすまして非公開データを収集する恐れがあります。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"システムの全般設定の変更"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"ライトの制御をアプリケーションに許可します。"</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"USBデバイスへのアクセス"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"USBデバイスへのアクセスをアプリケーションに許可します。"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTPプロトコルの実装"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"カーネルMTPドライバにアクセスしてMTP USBプロトコルを実装することを許可します。"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"ハードウェアのテスト"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"ハードウェアのテストのためにさまざまな周辺機器を制御することをアプリケーションに許可します。"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"電話番号発信"</string>
@@ -383,7 +381,7 @@
<string name="permlab_bindGadget" msgid="776905339015863471">"ウィジェットの選択"</string>
<string name="permdesc_bindGadget" msgid="2098697834497452046">"どのアプリケーションがどのウィジェットを使用できるかシステムに指定することをこのアプリケーションに許可します。これにより、アプリケーション間で個人データにアクセスできるようになります。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"端末ステータスの変更"</string>
- <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string>
+ <string name="permdesc_modifyPhoneState" msgid="3302284561346956587">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のON/OFFなどを通知せずに行うことができます。"</string>
<string name="permlab_readPhoneState" msgid="2326172951448691631">"携帯のステータスとIDの読み取り"</string>
<string name="permdesc_readPhoneState" msgid="188877305147626781">"端末の電話機能へのアクセスをアプリケーションに許可します。この権限が許可されたアプリケーションでは、この携帯の電話番号やシリアル番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"タブレットのスリープを無効化"</string>
@@ -393,7 +391,7 @@
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"タブレットの電源ON/OFF"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"電源のON/OFF"</string>
<string name="permdesc_devicePower" product="tablet" msgid="3853773100100451905">"タブレットの電源のON/OFFをアプリケーションに許可します。"</string>
- <string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"携帯電話の電源のオン/オフをアプリケーションに許可します。"</string>
+ <string name="permdesc_devicePower" product="default" msgid="4577331933252444818">"携帯電話の電源のON/OFFをアプリケーションに許可します。"</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"出荷時試験モードでの実行"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"タブレットハードウェアへのアクセスを完全に許可して、低レベルのメーカーテストを実行します。メーカーのテストモードでタブレットを使用する場合にのみ利用できます。"</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"携帯電話のハードウェアへのアクセスを完全に許可して、低レベルのメーカーテストとして実行します。メーカーのテストモードで携帯電話を使用するときのみ利用できます。"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SDカードのコンテンツを修正/削除する"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"USBストレージへの書き込みをアプリケーションに許可します。"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"SDカードへの書き込みをアプリケーションに許可します。"</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"内部メディアストレージの内容の変更/削除"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"内部メディアストレージの内容の変更をアプリケーションに許可します。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"キャッシュファイルシステムにアクセス"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"キャッシュファイルシステムへの読み書きをアプリケーションに許可します。"</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"インターネット通話の発着信"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ポリシーが有効になっている場合は端末のグローバルプロキシが使用されるように設定します。有効なグローバルプロキシを設定できるのは最初のデバイス管理者だけです。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"パスワードの有効期限の設定"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ストレージ暗号化の設定"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"保存したアプリケーションデータが暗号化されるようにする"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"自宅"</item>
<item msgid="869923650527136615">"携帯"</item>
@@ -604,8 +602,9 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"勤務先"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"その他"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PINコードを入力"</string>
- <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"ロックを解除するにはパスワードを入力"</string>
- <string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"ロックを解除するにはPINを入力"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"タップしてパスワードを入力"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"パスワードを入力"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"PINを入力"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PINコードが正しくありません。"</string>
<string name="keyguard_label_text" msgid="861796461028298424">"MENU、0キーでロック解除"</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"緊急通報番号"</string>
@@ -613,16 +612,16 @@
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"画面ロック中"</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"MENUキーでロック解除(または緊急通報)"</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"MENUキーでロック解除"</string>
- <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ロックを解除するパターンを入力"</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"パターンを入力"</string>
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"緊急通報"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"通話に戻る"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"一致しました"</string>
<string name="lockscreen_pattern_wrong" msgid="4817583279053112312">"やり直してください"</string>
<string name="lockscreen_password_wrong" msgid="6237443657358168819">"やり直してください"</string>
<string name="lockscreen_plugged_in" msgid="613343852842944435">"充電中(<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
- <string name="lockscreen_charged" msgid="4938930459620989972">"充電完了。"</string>
+ <string name="lockscreen_charged" msgid="4938930459620989972">"充電完了"</string>
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <string name="lockscreen_low_battery" msgid="1482873981919249740">"充電してください。"</string>
+ <string name="lockscreen_low_battery" msgid="1482873981919249740">"充電してください"</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"SIMカードが挿入されていません"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"タブレット内にSIMカードがありません。"</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"SIMカードが挿入されていません"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"パスワード"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ログイン"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ユーザー名またはパスワードが正しくありません。"</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"ユーザー名またはパスワードを忘れた場合は"\n<b>"google.com/accounts/recovery"</b>" にアクセス"</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"確認中..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"ロック解除"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"サウンドON"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"自動入力"</string>
<string name="setup_autofill" msgid="8154593408885654044">"自動入力設定"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$3$2$1"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">"、 "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ブラウザの履歴とブックマークを読み取る"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"ブラウザでアクセスしたすべてのURLおよびブラウザのすべてのブックマークの読み取りをアプリケーションに許可します。"</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"ブラウザの履歴とブックマークを書き込む"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
<string name="select_input_method" msgid="6865512749462072765">"入力方法の選択"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"入力方法の設定"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -969,7 +968,7 @@
<string name="no_file_chosen" msgid="6363648562170759465">"ファイルが選択されていません"</string>
<string name="reset" msgid="2448168080964209908">"リセット"</string>
<string name="submit" msgid="1602335572089911941">"送信"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードを有効にする"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードになっています"</string>
<string name="car_mode_disable_notification_message" msgid="668663626721675614">"運転モードを終了するには選択してください。"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"タップして設定する"</string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1件一致"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g>/<xliff:g id="TOTAL">%d</xliff:g>件"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"完了"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USBストレージのマウント解除中..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"SDカードのマウント解除中..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USBストレージ内のデータを消去中..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"共有"</string>
<string name="find" msgid="4808270900322985960">"検索"</string>
<string name="websearch" msgid="4337157977400211589">"ウェブ検索"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>さんからの現在地情報リクエスト"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"現在地情報へのアクセス許可"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g>さん(<xliff:g id="SERVICE">%2$s</xliff:g>)からのリクエスト"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"はい"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"いいえ"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"削除の制限を超えました"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>アカウントの<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>で<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>件の削除が指定されています。操作を選択してください。"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"アイテムを削除する"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"削除を元に戻す"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"今は何もしない"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNに接続しました"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが切断されました"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"タップしてVPNに再接続してください。"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"アカウントを選択"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"増やす"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"減らす"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 10eba59..704f453 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"종료 중..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"태블릿이 종료됩니다."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"휴대전화가 종료됩니다."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"종료하시겠습니까?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"최근에 사용한 앱이 없습니다."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"태블릿 옵션"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"비행기 모드"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"비행기 모드 사용"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"비행기 모드 사용 안함"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"요금이 부과되는 서비스"</string>
@@ -186,7 +184,7 @@
<string name="permdesc_statusBarService" msgid="4097605867643520920">"애플리케이션이 상태 표시줄이 되도록 허용합니다."</string>
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"상태 표시줄 확장/축소"</string>
<string name="permdesc_expandStatusBar" msgid="7088604400110768665">"애플리케이션이 상태 표시줄을 확장하거나 축소할 수 있도록 합니다."</string>
- <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"발신전화 가로채기"</string>
+ <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"발신전화 차단"</string>
<string name="permdesc_processOutgoingCalls" msgid="2228988201852654461">"애플리케이션이 발신전화를 처리하고 전화를 걸 번호를 변경할 수 있도록 합니다. 이 경우 악성 애플리케이션이 발신전화를 모니터링하거나, 다른 방향으로 돌리거나, 중단시킬 수 있습니다."</string>
<string name="permlab_receiveSms" msgid="2697628268086208535">"SMS 수신"</string>
<string name="permdesc_receiveSms" msgid="6298292335965966117">"애플리케이션이 SMS 메시지를 받고 처리할 수 있도록 합니다. 이 경우 악성 애플리케이션이 메시지를 모니터링하거나 사용자가 보기 전에 삭제할 수 있습니다."</string>
@@ -195,7 +193,7 @@
<string name="permlab_sendSms" msgid="5600830612147671529">"SMS 메시지 보내기"</string>
<string name="permdesc_sendSms" msgid="1946540351763502120">"애플리케이션이 SMS 메시지를 보낼 수 있도록 합니다. 이 경우 악성 애플리케이션이 사용자의 확인 없이 메시지를 전송하여 요금을 부과할 수 있습니다."</string>
<string name="permlab_readSms" msgid="4085333708122372256">"SMS 또는 MMS 읽기"</string>
- <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"애플리케이션이 태블릿 또는 SIM 카드에 저장된 SMS 메시지를 읽을 수 있도록 합니다. 이 경우 악성 애플리케이션이 기밀 메시지를 읽을 수 있습니다."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="5836710350295631545">"애플리케이션이 태블릿 또는 SIM 카드에 저장된 SMS 메시지를 읽을 수 있도록 합니다. 이 경우 악성 애플리케이션이 기밀 메시지를 읽을 수도 있습니다."</string>
<string name="permdesc_readSms" product="default" msgid="3002170087197294591">"애플리케이션이 휴대전화 또는 SIM 카드에 저장된 SMS 메시지를 읽을 수 있도록 합니다. 이 경우 악성 애플리케이션이 기밀 메시지를 읽을 수 있습니다."</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"SMS 또는 MMS 편집"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5332124772918835437">"애플리케이션이 태블릿 또는 SIM 카드에 저장된 SMS 메시지에 쓸 수 있도록 합니다. 단, 악성 애플리케이션이 이 기능을 이용하여 메시지를 삭제할 수 있습니다."</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"권한을 가진 프로그램이 입력 방법에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"배경화면 연결"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"권한을 가진 프로그램이 배경화면에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"위젯 서비스와 연결"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"보유자가 위젯 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 애플리케이션에는 필요하지 않습니다."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"기기 관리자와 상호 작용"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"보유자가 기기 관리자에게 인텐트를 보낼 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"화면 방향 변경"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"애플리케이션이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"애플리케이션 구성 요소 사용 또는 사용 안함"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"애플리케이션이 다른 애플리케이션 구성 요소 사용 여부를 변경할 수 있도록 합니다. 악성 애플리케이션이 이를 악용하여 중요한 태블릿 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 애플리케이션 구성 요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"애플리케이션이 다른 애플리케이션 구성 요소 사용 여부를 변경할 수 있도록 합니다. 악성 애플리케이션이 이를 악용하여 중요한 태블릿 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 애플리케이션 구성 요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"애플리케이션이 다른 애플리케이션 구성 요소 사용 여부를 변경할 수 있도록 합니다. 악성 애플리케이션이 이를 악용하여 중요한 휴대전화 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 애플리케이션 구성 요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"기본 애플리케이션 설정"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"애플리케이션이 기본 애플리케이션을 수정할 수 있도록 합니다. 이 경우 악성 애플리케이션이 사용자의 개인 정보를 수집하기 위해 기존 애플리케이션으로 위장하도록 실행되는 애플리케이션을 몰래 변경할 수 있습니다."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"전체 시스템 설정 수정"</string>
@@ -320,7 +320,7 @@
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"위치 정보 공급자 설치 권한"</string>
<string name="permdesc_installLocationProvider" msgid="5449175116732002106">"테스트용 가짜 위치 정보제공자를 만듭니다. 단, 악성 애플리케이션이 이 기능을 이용하여 GPS, 네트워크 공급업체 같은 실제 위치 소스에서 반환한 위치 및/또는 상태를 덮어쓰거나 사용자의 위치를 모니터링하여 외부 소스로 보고할 수 있습니다."</string>
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"자세한 (GPS) 위치"</string>
- <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"태블릿에서 GPS 등의 자세한 위치 정보를 사용합니다. 이 경우 악성 애플리케이션이 사용자의 위치를 확인하고 추가 배터리 전원을 소비할 수 있습니다."</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"태블릿에서 GPS 등의 자세한 위치 정보를 사용합니다. 이 경우 악성 애플리케이션이 사용자의 위치를 확인하고 추가 배터리 전원을 소비할 수도 있습니다."</string>
<string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"GPS 등의 자세한 위치 정보가 사용 가능한 경우 휴대전화에서 이를 사용합니다. 이 경우 악성 애플리케이션이 사용자의 위치를 확인하고 추가 배터리 전원을 소비할 수 있습니다."</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"네트워크 기반의 대략적인 위치"</string>
<string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"태블릿의 대략적인 위치를 측정하기 위해 셀룰러 네트워크 데이터베이스와 같은 광범위한 위치 정보를 사용합니다. 이 경우 악성 애플리케이션이 사용자의 위치를 대략적으로 측정할 수 있습니다."</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"애플리케이션이 카메라 플래시를 제어할 수 있도록 합니다."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"USB 장치 액세스"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"애플리케이션이 USB 장치에 액세스하도록 허용합니다."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP 프로토콜 구현"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"커널 MTP 드라이버에 액세스하여 MTP USB 프로토콜을 구현할 수 있도록 허용합니다."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"하드웨어 테스트"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"애플리케이션이 하드웨어를 테스트할 목적으로 다양한 주변장치를 제어할 수 있도록 합니다."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"전화번호 자동 연결"</string>
@@ -388,7 +386,7 @@
<string name="permdesc_readPhoneState" msgid="188877305147626781">"애플리케이션이 장치의 휴대전화 기능에 접근할 수 있도록 합니다. 이 권한을 갖는 애플리케이션은 휴대전화의 전화번호 및 일련번호, 통화가 활성인지 여부, 해당 통화가 연결된 번호 등을 확인할 수 있습니다."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"태블릿이 절전 모드로 전환되지 않도록 설정"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"휴대전화가 절전 모드로 전환되지 않도록 설정"</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"애플리케이션에서 태블릿이 절전 모드로 전환되지 않도록 합니다."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="4032181488045338551">"애플리케이션이 태블릿의 절전 모드를 사용중지할 수 있습니다."</string>
<string name="permdesc_wakeLock" product="default" msgid="7584036471227467099">"애플리케이션이 휴대전화가 절전 모드로 전환되지 않도록 합니다."</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"태블릿 전원 켜고 끄기"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"휴대전화 전원 켜고 끄기"</string>
@@ -401,7 +399,7 @@
<string name="permdesc_setWallpaper" msgid="6417041752170585837">"애플리케이션이 시스템 배경화면을 설정할 수 있도록 합니다."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"배경화면 크기 힌트 설정"</string>
<string name="permdesc_setWallpaperHints" msgid="6019479164008079626">"애플리케이션이 시스템 배경화면 크기 힌트를 설정할 수 있도록 합니다."</string>
- <string name="permlab_masterClear" msgid="2315750423139697397">"시스템을 기본값으로 재설정"</string>
+ <string name="permlab_masterClear" msgid="2315750423139697397">"시스템 초기화"</string>
<string name="permdesc_masterClear" msgid="5033465107545174514">"애플리케이션이 모든 데이터, 구성 및 설치된 애플리케이션을 지워서 시스템을 완전히 초기화할 수 있도록 합니다."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"시간 설정"</string>
<string name="permdesc_setTime" product="tablet" msgid="209693136361006073">"애플리케이션이 태블릿 시계의 시간을 변경할 수 있도록 합니다."</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SD 카드 콘텐츠 수정/삭제"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"애플리케이션에서 USB 저장소의 정보를 변경할 수 있습니다."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"애플리케이션이 SD 카드에 쓸 수 있도록 합니다."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"내부 미디어 저장소 콘텐츠 수정/삭제"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"애플리케이션이 내부 미디어 저장소의 콘텐츠를 수정할 수 있도록 합니다."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"캐시 파일시스템 액세스"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"애플리케이션이 캐시 파일시스템을 읽고 쓸 수 있도록 합니다."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"인터넷 전화 걸기/받기"</string>
@@ -484,12 +480,14 @@
<string name="policylab_forceLock" msgid="2274085384704248431">"화면 잠금"</string>
<string name="policydesc_forceLock" msgid="5696964126226028442">"화면을 잠그는 방법과 시기를 제어합니다."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"모든 데이터 삭제"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"초기화를 수행하여 경고 없이 태블릿 데이터를 지웁니다."</string>
- <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"초기화를 수행하여 경고 없이 휴대전화 데이터를 지웁니다."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"공장 초기화를 수행하여 경고 없이 태블릿 데이터를 지웁니다."</string>
+ <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"공장 초기화를 수행하여 경고 없이 휴대전화 데이터를 지웁니다."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"기기 전체 프록시 설정"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"비밀번호 만료 설정"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"저장소 암호화 설정"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"저장한 애플리케이션 데이터를 암호화해야 합니다."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"집"</item>
<item msgid="869923650527136615">"모바일"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"직장"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"기타"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN 코드 입력"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"비밀번호를 입력하려면 터치하세요."</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"잠금을 해제하려면 비밀번호 입력"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"잠금을 해제하려면 PIN 입력"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 코드가 잘못되었습니다."</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"비밀번호"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"로그인"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"사용자 이름 또는 비밀번호가 잘못되었습니다."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"사용자 이름이나 비밀번호를 잊어버렸습니까?"\n<b>"google.com/accounts/recovery"</b>"를 방문하세요."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"확인 중..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"잠금해제"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"사운드 켜기"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"자동완성"</string>
<string name="setup_autofill" msgid="8154593408885654044">"자동완성 설정"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$3$2$1"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"브라우저의 기록 및 북마크 읽기"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"애플리케이션이 브라우저로 방문한 모든 URL과 브라우저의 모든 북마크를 읽도록 허용합니다."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"브라우저의 기록 및 북마크 쓰기"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
<string name="select_input_method" msgid="6865512749462072765">"입력 방법 선택"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"입력 방법 구성"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string>
@@ -967,7 +966,7 @@
<string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"인증서 기반 L2TP/IPSec VPN"</string>
<string name="upload_file" msgid="2897957172366730416">"파일 선택"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"파일을 선택하지 않았습니다."</string>
- <string name="reset" msgid="2448168080964209908">"재설정"</string>
+ <string name="reset" msgid="2448168080964209908">"초기화"</string>
<string name="submit" msgid="1602335572089911941">"제출"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"운전모드 사용"</string>
<string name="car_mode_disable_notification_message" msgid="668663626721675614">"운전모드를 종료하려면 선택하세요."</string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"검색결과 1개"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g>/<xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"완료"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB 저장소 마운트 해제 중..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD 카드 마운트 해제 중..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB 저장소 지우는 중..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"공유"</string>
<string name="find" msgid="4808270900322985960">"찾기"</string>
<string name="websearch" msgid="4337157977400211589">"웹 검색"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>의 위치 요청"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"위치 요청"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"요청한 사람: <xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"예"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"아니요"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"삭제 한도를 초과했습니다."</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 계정에 대해 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>개의 삭제된 항목이 있습니다. 어떻게 하시겠습니까?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"항목 삭제"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"삭제 실행취소"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"나중에 작업"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결됨"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결 끊김"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"VPN에 다시 연결하려면 터치하세요."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"계정 선택"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"올리기"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"줄이기"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bbb629d..f3de6dd 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lėktuvo režimas"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"ĮJUNGTAS lėktuvo režimas"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"lėktuvo režimas IŠJUNGTAS"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
<string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Paslaugos, už kurias mokėjote"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Leidžia savininkui susisaistyti su įvesties būdo aukščiausio lygio sąsaja. Neturėtų reikėti įprastoms programoms."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"susaistyti su darbalaukio fonu"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Leidžia savininkui susisaistyti su aukščiausio lygio darbalaukio fono sąsaja. Neturėtų reikėti įprastose programose."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"susaistyti su valdiklio paslauga"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Leidžiama savininkui susisaistyti su aukščiausio lygio valdiklio paslaugos sąsaja. Neturėtų reikėti įprastose programose."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"sąveikauti su įrenginio administratoriumi"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Leidžia savininkui siųsti tikslus įrenginio administratoriui. Neturėtų reikėti įprastose programose."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"keisti ekrano padėtį"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Leidžia programai valdyti šviesos signalą."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"pasiekti USB įrenginius"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Leidžiama programai pasiekti USB įrenginius."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"taikyti MTP protokolą"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Leidžiama prieiga prie pagrindinės MTP tvarkyklės taikyti MTP USB protokolą."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"bandyti aparatinę įrangą"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Leidžia programai valdyti įvairius išorinius įrenginius aparatinės įrangos bandymo tikslais."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"skambinti tiesiogiai telefono numeriais"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"keisti / ištrinti SD kortelės turinį"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Leidžiama programai įrašyti į USB atmintinę."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Leidžia programai rašyti į SD kortelę."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"keisti / ištrinti vidinės medijos atmintinės turinį"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"keisti / ištr. vid. med. atm. tur."</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Leidžiama programai keisti vidinės medijos atmintinės turinį."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"pasiekti talpyklos failų sistemą"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Leidžia programai skaityti ir rašyti į talpyklos failų sistemą."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nustatyti įrenginio bendrąjį tarpinį serverį, kad būtų naudojamas, kol įgalinta politika. Tik pirmasis įrenginio administratorius nustato efektyvų bendrąjį tarpinį serverį."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nust. slaptaž. galiojimo pab."</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Valdyti, per kiek laiko iki ekrano užrakinimo turi būti pakeistas slaptažodis"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nustatyti atmintinės šifruotę"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Saugomos programos duomenys turi būti šifruoti"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Pagrindinis"</item>
<item msgid="869923650527136615">"Mobilusis"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbas"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Kita"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Įveskite PIN kodą"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Kad įvest. slaptaž., paliesk."</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Įveskite slaptažodį, kad atrakintumėte"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Jei norite atrakinti, įveskite PIN kodą"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Neteisingas PIN kodas!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Slaptažodis"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prisijungti"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neteisingas naudotojo vardas ar slaptažodis."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Pamiršote naudotojo vardą ar slaptažodį?"\n"Apsilankykite šiuo adresu: "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Tikrinama..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Atblokuoti"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Garsas įjungtas"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pasirinkti įvesties būdą"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigūruoti įvesties metodus"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Bendrinti"</string>
<string name="find" msgid="4808270900322985960">"Ieškoti"</string>
<string name="websearch" msgid="4337157977400211589">"Žiniat. paieška"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Vietos užklausa iš <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Vietos užklausa"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Užklausą pateikė <xliff:g id="NAME">%1$s</xliff:g> („<xliff:g id="SERVICE">%2$s</xliff:g>“)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Taip"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Viršytas ištrynimo apribojimas"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Yra <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> ištrinti (-ų) elementai (-ų), skirti (-ų) <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, „<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>“ paskyrai. Ką norite daryti?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Ištrinti elementus."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Anuliuoti ištrynimus."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Kol kas nieko nedaryti."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT prijungtas"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT atjungtas"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Jei norite iš naujo prisijungti prie VPT, palieskite."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Pasirinkti paskyrą"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Padidinti"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Sumažinti"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7ef1e0a..9756e91 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Lidojuma režīms"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Lidojuma režīms ir IESLĒGTS."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Lidojuma režīms ir IZSLĒGTS."</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Maksas pakalpojumi"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Ļauj īpašniekam saistīt ar ievades metodes augšējā līmeņa saskarni. Parastajām lietojumprogrammām nekad nav nepieciešama."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"saistīt ar tapeti"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Ļauj īpašniekam saistīties ar tapetes augšējā līmeņa saskarni. Parastajās lietojumprogrammās nekad nav nepieciešama."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"saistīt ar logrīka pakalpojumu"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Ļauj īpašniekam izveidot saiti ar logrīka pakalpojuma augšējā līmeņa saskarni. Parastajām lietojumprogrammām tas nekad nav nepieciešams."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"mijiedarboties ar ierīces administratoru"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Ļauj īpašniekam sūtīt nolūkus ierīces administratoram. Nekad nav nepieciešams parastajām lietojumprogrammām."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"mainīt ekrāna orientāciju"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Ļauj lietojumprogrammai kontrolēt uzliesmojumu."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"piekļuve USB ierīcēm"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Ļauj lietojumprogrammai piekļūt USB ierīcēm."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"Ieviests MTP protokols"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Ļauj piekļūt kodola MTP dzinim, lai ieviestu MTP USB protokolu."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"pārbaudīt aparatūru"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Ļauj lietojumprogrammai kontrolēt dažādas perifērijas ierīces aparatūras pārbaudīšanas nolūkos."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"tieši zvanīt uz tālruņa numuriem"</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"pārveidot/dzēst SD kartes saturu"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Ļauj lietoj. rakstīt USB kr."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Ļauj lietojumprogrammai rakstīt SD kartē."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"pārveidot/dzēst datu nesēja iekšējās krātuves saturu"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Ļauj lietojumprogrammai pārveidot iekšējas datu nesēja krātuves saturu."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"pārv./dz.datu n.iekš.atm.sat."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Ļauj lietojumprogrammai pārveidot datu nesēja iekšējas atmiņas saturu."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"piekļūt kešatmiņas failu sistēmai"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Ļauj lietojumprogrammai lasīt kešatmiņas failu sistēmu un rakstīt tajā."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"veikt/saņemt interneta zvanus"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Iestatiet izmantojamo ierīces globālo starpniekserveri, kad ir iespējota politika. Spēkā esošo globālo starpniekserveri iestata tikai pirmās ierīces administrators."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Paroles termiņa izb. iest."</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolē ekrāna bloķēšanas paroles maiņas intervālu"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Skatīt atmiņas šifrējumu"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Pieprasīt, lai saglabātie lietojumprogrammas dati tiktu šifrēti"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Mājas"</item>
<item msgid="869923650527136615">"Mobilais"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbs"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Cits"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Ievadiet PIN kodu"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Pieskarieties, lai ievadītu paroli"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Lai atbloķētu, ievadiet paroli."</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Lai atbloķētu, ievadiet PIN"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN kods nav pareizs."</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parole"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Pierakstīties"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Lietotājvārds vai parole nav derīga."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Vai aizmirsāt lietotājvārdu vai paroli?"\n"Apmeklējiet vietni "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Notiek pārbaude..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Atbloķēt"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Skaņa ir ieslēgta"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
<string name="select_input_method" msgid="6865512749462072765">"Atlasiet ievades metodi"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurēt ievades metodes"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Kopīgot"</string>
<string name="find" msgid="4808270900322985960">"Atrast"</string>
<string name="websearch" msgid="4337157977400211589">"Meklēt tīmeklī"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Atrašanās vietas pieprasījums no: <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Atrašanās vietas pieprasījums"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Pieprasīja: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Jā"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nē"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Pārsniegts dzēšanas ierobežojums"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Pavisam ir <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> dzēsti vienumi: <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> (kontam <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>). Ko vēlaties darīt?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Dzēsiet šos vienumus."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Atsauciet dzēšanu."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Pagaidām neveiciet nekādas darbības."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> Savienojums ar VPN ir izveidots"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> Savienojums ar VPN ir pārtraukts"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Pieskarieties, lai atkārtoti izveidotu savienojumu ar VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Atlasīt kontu"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Palielināt"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Samazināt"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 83fd2d3c..743c8df 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Avslutter…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Nettbrettet slås av."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonen vil bli slått av."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Vil du slå av?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Ingen nylig brukte applikasjoner."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Innstillinger for nettbrett"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Flymodus"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flymodus er på"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flymodus er av"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"Over 100"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Betaltjenester"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Lar applikasjonen binde til toppnivågrensesnittet for en inndatametode. Vanlige applikasjoner bør aldri trenge dette."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind til bakgrunnsbilde"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Lar innehaveren binde det øverste nivået av grensesnittet til en bakgrunnsbilder. Skal ikke være nødvendig for vanlige programmer."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind til modultjenste"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Lar innehaveren binde til det øverste nivået av grensesnittet for en modultjeneste. Skal aldri være nødvendig for normale programmer."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"kommuniser med enhetsadministrator"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Tillater innehaveren å sende hensikter til enhetsadministrator. Bør aldri være nødvendig for normale programmer."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"snu skjermen"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Lar applikasjonen lese og skrive enhver ressurs eid av gruppen diag; for eksempel, filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør KUN brukes for maskinvarespesifikke diagnoseverktøy laget av operatøren eller produsenten."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"aktivere eller deaktigere applikasjonskomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Lar programmet endre på hvorvidt en komponent i et annet program er aktivert eller ikke. Skadelige programmer kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne rettigheten må brukes med forsiktighet, ettersom det er mulig å få programkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Lar programmet endre på hvorvidt en komponent i et annet program er aktivert eller ikke. Skadelige programmer kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne rettigheten må brukes med forsiktighet, ettersom det er mulig å få programkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Lar programmet endre på hvorvidt en komponent i et annet program er aktivert eller ikke. Skadelige programmer kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne rettigheten må brukes med forsiktighet, ettersom det er mulig å få programkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"velge foretrukne applikasjoner"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Lar applikasjonen endre valgene for foretrukne applikasjoner. Dette kan gi ondsinnede applikasjoner tilgang til i det stille å endre hvilke applikasjoner som kjøres, og slik gi seg ut til å være en eksisterende applikasjon og samle private data."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Lar applikasjonen kontrollere lommelykten."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"tilgang til USB-enheter"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Tillater programmet å få tilgang til USB-enheter."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementer MTP-protokoll"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Tillater tilgang til kjerne-MTP-driver for implementering av MTP USB-protokollen."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"teste maskinvare"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Lar applikasjonen styre diverse enheter med det formål å teste maskinvaren."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"ringe telefonnummer direkte"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"redigere/slette innhold på minnekort"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Prog. skriver til USB-lagr."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Lar applikasjonen skrive til minnekortet."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"endre eller slette innhold på interne medier"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Tillater et program til å endre innholdet i interne medier."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"tilgang til bufrede filer"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Tillater et program å lese og skrive til bufrede filer."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"foreta/motta Internett-anrop"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angir den globale mellomtjeneren på enheten som skal brukes når regelen er aktivert. Kun den opprinnelige administratoren av enheten kan angi den globale mellomtjeneren."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Angi utløpsdato for passordet"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Angi lagringskryptering"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Krever at lagrede programdata krypteres"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjemmenummer"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbeid"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Annen"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Skriv inn PIN-kode:"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Trykk og oppgi passord"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Skriv inn passord for å låse opp"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Skriv inn personlig kode for å låse opp"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Gal PIN-kode!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passord"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logg på"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ugyldig brukernavn eller passord."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Har du glemt brukernavnet eller passordet?"\n"Gå til"<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerer ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås opp"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Lyd på"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Autofyll"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Konfig. autofyll"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lese nettleserens logg og bokmerker"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Lar applikasjonen lese alle adresser nettleseren har besøkt, og alle nettleserens bokmerker."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skrive til nettleserens logg og bokmerker"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
<string name="select_input_method" msgid="6865512749462072765">"Velg inndatametode"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurer inndatametoder"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 treff"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> av <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Ferdig"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Kobler fra USB-lagring ..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Kobler fra SD-kort ..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Sletter USB-lagring ..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Del"</string>
<string name="find" msgid="4808270900322985960">"Finn"</string>
<string name="websearch" msgid="4337157977400211589">"Nettsøk"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Posisjonsforespørsel fra <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Posisjonsforespørsel"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Forespurt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nei"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Slettegrense overskredet"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Det finnes <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> slettede elementer for <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Hva vil du gjøre?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Slett elementene."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Opphev slettinger."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Ikke gjør noe nå."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> er tilkoblet VPN"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> er frakoblet VPN"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Trykk for å koble til et VPN på nytt."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Velg en konto"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Øke"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Senke"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3c03980..a149a53 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Uitschakelen..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Uw tablet wordt uitgeschakeld."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Uw telefoon wordt uitgeschakeld."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Wilt u afsluiten?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Geen recente toepassingen."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tabletopties"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Vliegmodus"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Vliegmodus is AAN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Vliegmodus is UIT"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Services waarvoor u moet betalen"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Hiermee staat u de houder toe zich te verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"verbinden met een achtergrond"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Hiermee staat u de houder toe zich te verbinden met de hoofdinterface van een achtergrond. Nooit vereist voor normale toepassingen."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"verbinden met een widgetservice"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Hiermee staat u de houder toe verbinding te maken met de hoofdinterface van een widgetservice. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interactie met apparaatbeheer"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Staat de houder toe intenties te verzenden naar een apparaatbeheerder. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"schermstand wijzigen"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Hiermee kan een toepassing lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of operator."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"toepassingscomponenten in- of uitschakelen"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Hiermee kan een toepassing bepalen of een component van een andere toepassing is ingeschakeld. Schadelijke toepassingen kunnen hiervan gebruik maken om belangrijke tabletfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien toepassingscomponenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Hiermee kan een toepassing bepalen of een component van een andere toepassing is ingeschakeld. Schadelijke toepassingen kunnen hiervan gebruik maken om belangrijke tabletfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien toepassingscomponenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Hiermee kan een toepassing bepalen of een component van een andere toepassing is ingeschakeld. Schadelijke toepassingen kunnen dit gebruiken om belangrijke telefoonfuncties uit te schakelen. Een machtiging moet zorgvuldig worden overwogen, aangezien toepassingscomponenten onbruikbaar, inconsistent of instabiel kunnen worden."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"voorkeurstoepassingen instellen"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Hiermee kan een toepassing uw voorkeurstoepassingen wijzigen. Schadelijke toepassingen kunnen op deze manier de actieve toepassingen zonder uw medeweten wijzigen en uw bestaande toepassingen doorzoeken om privégegevens van u te verzamelen."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"algemene systeeminstellingen wijzigen"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Hiermee kan de toepassing de zaklamp bedienen."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"toegang krijgen tot USB-apparaten"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Hiermee kan de toepassing toegang krijgen tot USB-apparaten."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP-protocol implementeren"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Staat toegang tot de kernel van de MTP-driver toe voor het implementeren van het MTP-USB-protocol."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"hardware testen"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Hiermee kan de toepassing verschillende randapparaten beheren om de hardware te testen."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"telefoonnummers rechtstreeks bellen"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"inhoud op de SD-kaart aanpassen/verwijderen"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Hiermee kan een toepassing schrijven naar de USB-opslag."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Hiermee kan een toepassing schrijven naar de SD-kaart."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"inh. mediaopsl. wijz./verw."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Hiermee kan een toepassing de inhoud van interne mediaopslag aanpassen."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"het cachebestandssysteem openen"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Staat een toepassing toe het cachebestandssysteem te lezen en te schrijven."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"internetoproepen starten/ontvangen"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Stel de algemene proxy voor het apparaat in die moet worden gebruikt terwijl het beleid is geactiveerd. Alleen de eerste apparaatbeheerder stelt de algemene proxy in."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Verval wachtwoord instellen"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Codering voor opslag instellen"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Vereisen dat opgeslagen toepassingsgegevens kunnen worden gecodeerd"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Thuis"</item>
<item msgid="869923650527136615">"Mobiel"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Werk"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Overig"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN-code invoeren"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Raak aan om wachtwoord op te geven"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Voer het wachtwoord in om te ontgrendelen"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Voer de PIN-code in om te ontgrendelen"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Onjuiste PIN-code!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Wachtwoord"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Aanmelden"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Gebruikersnaam of wachtwoord ongeldig."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Bent u uw gebruikersnaam of wachtwoord vergeten?"\n"Ga naar "<b>"https://www.google.com/accounts/recovery?hl=nl"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Controleren..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ontgrendelen"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Geluid aan"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"AutoFill"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Aut. aanv. inst."</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"browsergeschiedenis en bladwijzers lezen"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Hiermee kan een toepassing de URL\'s lezen die u via de browser heeft bezocht, evenals alle bladwijzers van de browser."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"browsergeschiedenis en bladwijzers schrijven"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
<string name="select_input_method" msgid="6865512749462072765">"Invoermethode selecteren"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Invoermethoden configureren"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 overeenkomst"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> van <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Gereed"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB-opslag ontkoppelen..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD-kaart ontkoppelen..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB-opslag wissen..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Delen"</string>
<string name="find" msgid="4808270900322985960">"Vinden"</string>
<string name="websearch" msgid="4337157977400211589">"Online zoeken"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Locatieverzoek van <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Locatieverzoek"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Aangevraagd door <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nee"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Verwijderingslimiet overschreden"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Wat wilt u doen?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"De items verwijderen."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Verwijderingen ongedaan maken."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Nu niets doen."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> verbonden via VPN"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN-verbinding met <xliff:g id="PROFILENAME">%s</xliff:g> verbroken"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Raak aan om opnieuw verbinding te maken met een VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Selecteer een account"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Hoger"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Lager"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e82dbca..3035e96 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -50,7 +50,7 @@
<string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
<string name="ClipMmi" msgid="6952821216480289285">"Identyfikator rozmówcy przy połączeniach przychodzących"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Identyfikator rozmówcy przy połączeniach wychodzących"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Przekierowania połączeń"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Przekazywanie połączeń"</string>
<string name="CwMmi" msgid="9129678056795016867">"Połączenia oczekujące"</string>
<string name="BaMmi" msgid="455193067926770581">"Blokada dzwonienia"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Zmiana hasła"</string>
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Wyłączanie..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet zostanie wyłączony."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon zostanie wyłączony"</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Czy chcesz wyłączyć?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Brak ostatnio używanych aplikacji."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opcje tabletu"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Tryb samolotowy"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Tryb samolotowy jest włączony"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Tryb samolotowy jest wyłączony"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
<string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Usługi płatne"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu metody wejściowej. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"powiązanie z tapetą"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Umożliwia posiadaczowi powiązać interfejs najwyższego poziomu dla tapety. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"powiązanie z usługą widżetów"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Zezwala posiadaczowi na powiązanie z interfejsem najwyższego poziomu usługi widżetów. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcja z administratorem urządzenia"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Zezwala posiadaczowi na wysyłanie informacji o zamiarach do administratora urządzenia. Opcja nie powinna być nigdy potrzebna w przypadku zwykłych aplikacji."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"zmienianie orientacji ekranu"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Pozwala aplikacji na czytanie i zapisywanie we wszystkich zasobach posiadanych przez diagnozowaną grupę, jak na przykład pliki w katalogu /dev. Może to potencjalnie wpłynąć na stabilność i bezpieczeństwo systemu. Powinno być wykorzystywane TYLKO w celach diagnozowania sprzętu przez producenta lub operatora."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"włączanie lub wyłączanie składników aplikacji"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Zezwala aplikacji na zmianę ustawienia określającego, czy składnik innej aplikacji ma być włączony. Złośliwe aplikacje mogą wykorzystać tę możliwość w celu wyłączenia ważnych funkcji tabletu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ składniki aplikacji mogą znaleźć się w stanie, w którym będą one bezużyteczne, niezgodne lub niestabilne."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Zezwala aplikacji na zmianę ustawienia określającego, czy składnik innej aplikacji ma być włączony. Złośliwe aplikacje mogą wykorzystać tę możliwość w celu wyłączenia ważnych funkcji tabletu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ składniki aplikacji mogą znaleźć się w stanie, w którym będą one bezużyteczne, niezgodne lub niestabilne."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Zezwala aplikacji na zmianę ustawienia określającego, czy składnik innej aplikacji ma być włączony. Złośliwe aplikacje mogą wykorzystać tę możliwość w celu wyłączenia ważnych funkcji telefonu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ składniki aplikacji mogą znaleźć się w stanie, w którym będą one bezużyteczne, niezgodne lub niestabilne."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ustawianie preferowanych aplikacji"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Umożliwia aplikacji zmianę preferowanych programów użytkownika. Może to pozwolić szkodliwym aplikacjom na niezauważalną podmianę uruchamianych programów, aby zbierać prywatne dane użytkownika."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modyfikowanie ogólnych ustawień systemu"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Pozwala aplikacji kontrolować latarkę."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"dostęp do urządzeń USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Zezwala aplikacji na dostęp do urządzeń USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementowanie protokołu MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Zezwala na dostęp do sterownika MTP jądra w celu implementacji protokołu USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testowanie sprzętu"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Pozwala aplikacji na kontrolowanie różnych urządzeń peryferyjnych w celu testowania sprzętu."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"bezpośrednie wybieranie numerów telefonów"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modyfikowanie/usuwanie zawartości karty SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Umożliwia zapis na nośnik USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Umożliwia aplikacji zapis na karcie SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modyf./usuw. zawartości pam. wewn."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Zezwala aplikacji na modyfikowanie zawartości pamięci wewnętrznej."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"dostęp do systemu plików pamięci podręcznej"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Zezwala aplikacji na odczyt i zapis w systemie plików pamięci podręcznej."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"nawiązywanie/odbieranie połączeń przez internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ustaw globalny serwer proxy urządzenia do wykorzystywania przy włączonych zasadach. Tylko pierwszy administrator urządzenia ustawia obowiązujący globalny serwer proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ustaw wygasanie hasła"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ustaw szyfrowanie pamięci"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Wymaga szyfrowania danych zapisanych aplikacji"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Dom"</item>
<item msgid="869923650527136615">"Komórka"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Służbowy"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Inny"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Wprowadź kod PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Dotknij, aby podać hasło"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Wprowadź hasło, aby odblokować"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Wprowadź kod PIN, aby odblokować"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Błędny kod PIN!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Hasło"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Zaloguj się"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Błędna nazwa użytkownika lub hasło."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Nie pamiętasz nazwy użytkownika lub hasła?"\n"Odwiedź stronę "<b>"google.pl/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Trwa sprawdzanie..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odblokuj"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Włącz dźwięk"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Autouzupełnianie"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Konfiguruj autouzupełnianie"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"odczyt historii i zakładek przeglądarki"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Umożliwia aplikacji odczyt wszystkich adresów URL odwiedzonych przez przeglądarkę, a także wszystkich zakładek przeglądarki."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"zapis historii i zakładek przeglądarki"</string>
@@ -709,7 +707,7 @@
<item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> godzin temu"</item>
</plurals>
<plurals name="last_num_days">
- <item quantity="other" msgid="3069992808164318268">"Ostatnie dni (<xliff:g id="COUNT">%d</xliff:g>)"</item>
+ <item quantity="other" msgid="3069992808164318268">"Ostatnie (<xliff:g id="COUNT">%d</xliff:g>) dni"</item>
</plurals>
<string name="last_month" msgid="3959346739979055432">"Ostatni miesiąc"</string>
<string name="older" msgid="5211975022815554840">"Starsze"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Wybierz metodę wprowadzania"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfiguruj metody wprowadzania"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string>
@@ -971,7 +970,7 @@
<string name="submit" msgid="1602335572089911941">"Prześlij"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Tryb samochodowy włączony"</string>
<string name="car_mode_disable_notification_message" msgid="668663626721675614">"Wybierz, aby zakończyć tryb samochodowy."</string>
- <string name="tethered_notification_title" msgid="3146694234398202601">"Jest aktywne powiązanie lub punkt dostępu"</string>
+ <string name="tethered_notification_title" msgid="3146694234398202601">"Aktywny tethering lub punkt dostępu"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"Dotknij, aby skonfigurować"</string>
<string name="back_button_label" msgid="2300470004503343439">"Wróć"</string>
<string name="next_button_label" msgid="1080555104677992408">"Dalej"</string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 wynik"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> z <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Gotowe"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Odłączanie nośnika USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Odłączanie karty SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Czyszczenie nośnika USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Udostępnij"</string>
<string name="find" msgid="4808270900322985960">"Znajdź"</string>
<string name="websearch" msgid="4337157977400211589">"Wyszukiwarka"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Prośba o lokalizację od użytkownika <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Prośba o lokalizację"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Żądane przez <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Tak"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nie"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Przekroczono limit usuwania"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Usunięte elementy: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> dla <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> na koncie <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Co chcesz zrobić?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Usuń elementy."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Cofnij usunięcie."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Nie wykonuj teraz żadnych czynności."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Połączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Rozłączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Dotknij, aby ponownie połączyć się z siecią VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Wybierz konto"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Zwiększ"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmniejsz"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 41634f8..f6ab376 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"A encerrar..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"O seu tablet irá encerrar."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone irá encerrar."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Pretende encerrar?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Nenhuma aplicação recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opções do tablet"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo de avião"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"O modo de voo está activado"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"O modo de voo está desactivado"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serviços que implicam pagamento"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite ao titular vincular a interface de nível superior a um método de entrada de som. Nunca deve ser necessário para aplicações normais."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a uma imagem de fundo"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite ao titular vincular a interface de nível superior de uma imagem de fundo. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a um serviço de widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permite que o titular vincule a interface de nível superior de um serviço de widget. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com um administrador do dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permite ao titular enviar intenções para um administrador do dispositivo. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"mudar orientação do ecrã"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Permite a uma aplicação ler e escrever em qualquer recurso que seja propriedade do grupo diag. Por exemplo, ficheiros em /dev. Isto pode afectar potencialmente a estabilidade e a segurança do sistema e deve ser utilizado APENAS para diagnósticos específicos do hardware pelo fabricante ou pelo operador."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"activar ou desactivar componentes da aplicação"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite a uma aplicação mudar a opção de activar ou não um componente de outra aplicação. Algumas aplicações maliciosas podem utilizar este item para desactivar funcionalidades importantes do tablet. É necessário ter cuidado com a autorização, uma vez que é possível tornar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite a uma aplicação mudar a opção de activar ou não um componente de outra aplicação. Algumas aplicações maliciosas podem utilizar este item para desactivar funcionalidades importantes do tablet. É necessário ter cuidado com a autorização, uma vez que é possível tornar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que uma aplicação altere a opção de activar ou não um componente de outra aplicação. As aplicações maliciosas podem utilizar este item para desactivar funcionalidades importantes do telefone. É necessário ter cuidado com esta permissão, uma vez que é possível tornar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"definir aplicações preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permite a uma aplicação modificar as suas aplicações preferidas. Isto pode permitir que algumas aplicações maliciosas mudem, de forma silenciosa, as aplicações executadas, falsificando as aplicações existentes para recolher os seus dados privados."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar definições globais do sistema"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permite à aplicação controlar a lanterna."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"aceder a dispositivos USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Permite à aplicação aceder a dispositivos USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementar protocolo MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite o acesso ao controlador MTP de kernel para implementar o protocolo MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testar hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permite à aplicação controlar vários periféricos para fins de teste de hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"marcar números de telefone directamente"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/eliminar conteúdo do cartão SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permite que uma aplicação escreva no armaz. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permite que uma aplicação escreva no cartão SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/eliminar conteúdo de suportes de armazenamento interno"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permite à aplicação modificar o conteúdo dos suportes de armazenamento interno."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"aceder ao sistema de ficheiros da cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permite a uma aplicação ler e escrever no sistema de ficheiros da cache."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"fazer/receber chamadas pela internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir o proxy global do aparelho a ser utilizado quando a política estiver activada. Só o primeiro administrador do aparelho define o proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Def. valid. da palavra-passe"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Def. encriptação armazenamento"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Requerer encriptação dos dados da aplicação armazenados"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residência"</item>
<item msgid="869923650527136615">"Móvel"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduzir código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Toque introduzir palavra-passe"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Introduza a palavra-passe para desbloquear"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Introduza o PIN para desbloquear"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Código PIN incorrecto!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Palavra-passe"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Iniciar sessão"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de utilizador ou palavra-passe inválidos."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Esqueceu-me do nome de utilizador ou da palavra-passe?"\n"Visite "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"A verificar..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som activado"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Pr. aut."</string>
<string name="setup_autofill" msgid="8154593408885654044">"Conf preench aut"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e marcadores do browser"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que a aplicação leia todos os URLs visitados pelo browser e todos os marcadores do browser."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"gravar histórico e marcadores do browser"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 correspondência"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"A desmontar armazenamento USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"A desmontar cartão SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"A apagar armazenamento USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Partilhar"</string>
<string name="find" msgid="4808270900322985960">"Localizar"</string>
<string name="websearch" msgid="4337157977400211589">"Pesquisar na Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Pedido de localização de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Pedido de localização"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Pedido por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limite de eliminações excedido"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Existem <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens eliminados para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que pretende fazer?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Eliminar os itens."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Anular as eliminações."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Não fazer nada por agora."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> ligada"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desligada"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Toque para voltar a ligar a uma VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Seleccionar conta"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuir"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 572cbce..6542cd3 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Encerrando…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Seu tablet será desligado."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"O seu telefone será desligado."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Gostaria de desligar?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Nenhum aplicativo recente."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opções do tablet"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo de avião"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modo de avião ATIVADO"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modo de avião DESATIVADO"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"Mais de cem"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Serviços que geram gastos"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite que o detentor se sujeite à interface de nível superior de um método de entrada. Aplicativos normais não devem precisar disso em momento algum."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sujeitar-se a um plano de fundo"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite que o detentor se sujeite à interface de nível superior de um plano de fundo. Aplicativos normais não devem precisar disso em momento algum."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sujeitar-se a um serviço de widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permite que o detentor se sujeite à interface de nível superior de um serviço de widget. Aplicativos normais não devem precisar disso em momento algum."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interagir com o administrador de um dispositivo"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permite que o detentor envie tentativas ao administrador de um dispositivo. Não é necessário para aplicativos normais."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"alterar orientação da tela"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo de diagnósticos; por exemplo, arquivos em /dev. Isso possivelmente pode afetar a estabilidade e a segurança do sistema. Isso deve ser usado APENAS para diagnósticos específicos do hardware realizados pelo fabricante ou pelo operador."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"ativar ou desativar os componentes do aplicativo"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Permite que um aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar isso para desativar recursos importantes do tablet. É preciso ter cuidado com essa permissão, pois é possível deixar os componentes do aplicativo em um estado inutilizável, inconsistente ou instável."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que um aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar isso para desativar recursos importantes do tablet. É preciso ter cuidado com essa permissão, pois é possível deixar os componentes do aplicativo em um estado inutilizável, inconsistente ou instável."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Permite que um aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar isso para desativar recursos importantes do telefone. É preciso ter cuidado com essa permissão, pois é possível deixar os componentes do aplicativo em um estado inutilizável, inconsistente ou instável."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"definir os aplicativos preferidos"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Permite que um aplicativo modifique os seus aplicativos preferidos. Isso pode permitir que aplicativos maliciosos alterem silenciosamente os aplicativos em execução, falsificando os seus aplicativos existentes para coletar os seus dados particulares."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar configurações globais do sistema"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permite que o aplicativo controle a lanterna."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"acessar dispositivos USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Permitir que o aplicativo acesse dispositivos USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementar protocolo MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite acesso ao driver MTP do núcleo para implementar o protocolo USB MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testar hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permite que o aplicativo controle diversos periféricos para teste do hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"chamar diretamente os números de telefone"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificar/excluir conteúdo do cartão SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Perm. aplic. grave arm. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permite que um aplicativo grave no cartão SD."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificar/excluir conteúdos de armazenamento de mídia internos"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permite que um aplicativo modifique os conteúdos de armazenamento de mídia internos."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"acessar o sistema de arquivos de cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permite que um aplicativo leia e grave no sistema de arquivos de cache."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"fazer/receber chamadas pela internet"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Definir validade da senha"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Definir criptografia de armazenamento"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Exigir que os dados do aplicativo armazenado sejam criptografados"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residencial"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Comercial"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Outros"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Digite o código PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Toque para inserir sua senha"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Digite a senha para desbloquear"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Digite o PIN para desbloquear"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Código PIN incorreto!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Senha"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Fazer login"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nome de usuário ou senha inválidos."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Esqueceu seu nome de usuário ou senha?"\n"Acesse "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verificando..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Som ativado"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Preenchimento automático"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Conf preen autom"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e favoritos do Navegador"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Permite que o aplicativo leia todos os URLs visitados pelo Navegador e todos os favoritos do Navegador."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"gravar histórico e favoritos do Navegador"</string>
@@ -813,7 +811,7 @@
<string name="capital_on" msgid="1544682755514494298">"ATIVADO"</string>
<string name="capital_off" msgid="6815870386972805832">"DESATIVADO"</string>
<string name="whichApplication" msgid="4533185947064773386">"Complete a ação usando"</string>
- <string name="alwaysUse" msgid="4583018368000610438">"Use o como padrão para esta ação."</string>
+ <string name="alwaysUse" msgid="4583018368000610438">"Usar como padrão para esta ação."</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Limpar o padrão em Configurações da página inicial > Aplicativos > Gerenciar aplicativos."</string>
<string name="chooseActivity" msgid="1009246475582238425">"Selecionar uma ação"</string>
<string name="noApplications" msgid="1691104391758345586">"Nenhum aplicativo pode realizar esta ação."</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configurar métodos de entrada"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"Uma correspondência"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> de <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Concluído"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Desconectando armazenamento USB..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Desconectando cartão SD..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Apagando o armazenamento USB..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Compartilhar"</string>
<string name="find" msgid="4808270900322985960">"Localizar"</string>
<string name="websearch" msgid="4337157977400211589">"Pesquisa na web do Google"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limite de exclusão excedido"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Há <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> itens excluídos para <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, conta <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. O que você deseja fazer?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Excluir os itens."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Desfazer as exclusões."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Não fazer nada por enquanto."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Toque para reconectar-se a uma VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Selecione uma conta"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Redução"</string>
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9a879c7..e28b304 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -259,6 +259,10 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permetta da sa fixar al nivel d\'interfatscha pli aut dad ina metoda d\'endataziun. Betg previs per applicaziuns normalas."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sa fixar vid in fund davos"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permetta da sa fixar al nivel d\'interfatscha pli aut dad ina metoda d\'endataziun. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permlab_bindRemoteViews (5697987759897367099) -->
+ <skip />
+ <!-- no translation found for permdesc_bindRemoteViews (2930855984822926963) -->
+ <skip />
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacziun cun in administratur dad apparats"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permetta al possessur da trametter intenziuns a l\'administratur dal apparat periferic. Betg previs per applicaziuns normalas."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"midar l\'orientaziun dal visur"</string>
@@ -498,6 +502,10 @@
<skip />
<!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
<skip />
+ <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+ <skip />
+ <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+ <skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
<item msgid="869923650527136615">"Telefonin"</item>
@@ -632,6 +640,8 @@
<!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
<skip />
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Endatar il code PIN"</string>
+ <!-- no translation found for keyguard_password_entry_touch_hint (7906561917570259833) -->
+ <skip />
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Endatai il pled-clav per debloccar."</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Endatar il PIN per debloccar"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Code PIN nuncorrect!"</string>
@@ -677,6 +687,8 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Pled-clav"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"S\'annunziar"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Num d\'utilisader u pled-clav nunvalid."</string>
+ <!-- no translation found for lockscreen_glogin_account_recovery_hint (8253152905532900548) -->
+ <skip />
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verifitgar..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Debloccar"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Tun activà"</string>
@@ -947,6 +959,8 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB connectà"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Tscherner per deactivar il debugging USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Tscherner ina metoda d\'endataziun"</string>
+ <!-- no translation found for configure_input_methods (6324843080254191535) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -1083,4 +1097,16 @@
<skip />
<!-- no translation found for sync_do_nothing (8717589462945226869) -->
<skip />
+ <!-- no translation found for vpn_notification_title_connected (3197819122581348515) -->
+ <skip />
+ <!-- no translation found for vpn_notification_title_disconnected (4614192702448522822) -->
+ <skip />
+ <!-- no translation found for vpn_notification_hint_disconnected (4689796928510104200) -->
+ <skip />
+ <!-- no translation found for choose_account_label (4191313562041125787) -->
+ <skip />
+ <!-- no translation found for number_picker_increment_button (4830170763103463443) -->
+ <skip />
+ <!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d0e1dc6..5326a4c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Mod Avion"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Modul Avion este ACTIVAT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modul avion este DEZACTIVAT"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicii cu plată"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Permite deţinătorului să se conecteze la interfaţa de nivel superior a unei metode de intrare. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"conectare la o imagine de fundal"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unei imagini de fundal. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"conectare la un serviciu widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu widget. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacţionare cu administratorul unui dispozitiv"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Permite proprietarului să trimită intenţii către un administrator al dispozitivului. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"modificare orientare ecran"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Permite aplicaţiei să controleze lanterna."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"accesare dispozitive USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Permite aplicaţiei să acceseze dispozitive USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementare protocol MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite accesul la driverul MTP al nucleului pentru a implementa protocolul USB pentru MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testare hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Permite aplicaţiei să controleze diverse periferice în scopul testării componentelor hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"apelare directă numere de telefon"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modificare/ştergere conţinut card SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Permite unei apl. să scrie în stoc. USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Permite unei aplicaţii să scrie pe cardul SD."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modificare/ştergere a conţinutului din stocarea media internă"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"modif./şterg. conţinutul media stocat intern"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Permite unei aplicaţii să modifice conţinutul stocării media interne."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"accesare sistem de fişiere cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Permite unei aplicaţii să scrie şi să citească sistemul de fişiere cache."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setaţi serverul proxy global pentru dispozitiv care să fie utilizat cât timp politica este activă. Numai primul administrator al dispozitivului poate seta serverul proxy global activ."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Setaţi expirarea parolei"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Controlarea duratei până când parola de blocare a ecranului trebuie modificată"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setaţi criptarea stocării"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Necesită ca datele aplicaţiei stocate să fie criptate"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domiciliu"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Serviciu"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Altul"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Introduceţi codul PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Ating. şi intr. parola"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Introduceţi parola pentru a debloca"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Introduceţi PIN pentru deblocare"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Cod PIN incorect!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parolă"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Conectaţi-vă"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nume de utilizator sau parolă nevalide."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Aţi uitat numele de utilizator sau parola?"\n"Accesaţi "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Se verifică..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Deblocaţi"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Selectaţi pentru a dezactiva depanarea USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Selectaţi metoda de intrare"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Configuraţi metode de intrare"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Distribuiţi"</string>
<string name="find" msgid="4808270900322985960">"Găsiţi"</string>
<string name="websearch" msgid="4337157977400211589">"Căutare pe web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitare de locaţie de la <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitare de locaţie"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitat de <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nu"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Limita pentru ştergere a fost depăşită"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Există <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> (de) elemente şterse pentru <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, contul <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ce doriţi să faceţi?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Ştergeţi elementele."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Anulaţi aceste ştergeri."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Pentru moment, nu efectuaţi nicio acţiune."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectat"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconectat"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Atingeţi pentru a vă reconecta la o reţea VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Selectaţi un cont"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementaţi"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrementaţi"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 22ee02a..436d09b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Выключение..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшетный ПК будет отключен."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон будет выключен."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Завершить работу?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Нет последних приложений."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Настройки планшетного ПК"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Режим полета"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим полета ВКЛЮЧЕН"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим полета ВЫКЛЮЧЕН"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Платные услуги"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Позволяет выполнять привязку к интерфейсу ввода верхнего уровня. Не требуется для обычных приложений."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"связать с фоновым рисунком"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Разрешает выполнять привязку к интерфейсу фонового рисунка верхнего уровня. Не требуется для обычных приложений."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"привязка к службе виджетов"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Разрешает выполнять привязку к интерфейсу верхнего уровня службы виджетов. Не требуется для обычных приложений."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаимодействовать с администратором устройства"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Позволяет владельцу отправлять целевые значения администратору устройства. Никогда не используется обычными приложениями."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"изменять ориентацию экрана"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Позволяет приложению считывать и записывать данные в любые ресурсы, принадлежащие группе диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Эта возможность может быть использована ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"включать или отключать компоненты приложения"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Позволяет приложению отключать или включать компоненты другого приложения. Вредоносные приложения могут использовать это разрешение для отключения важных возможностей планшетного ПК. Это разрешение следует использовать с осторожностью, так как оно может привести к несовместимости, нестабильности и неработоспособности компонентов приложения."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Позволяет приложению отключать или включать компоненты другого приложения. Вредоносные приложения могут использовать это разрешение для отключения важных возможностей планшетного ПК. Это разрешение следует использовать с осторожностью, так как оно может привести к несовместимости, нестабильности и неработоспособности компонентов приложения."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Позволяет приложению отключать или включать компоненты другого приложения. Вредоносные приложения могут использовать это разрешение для отключения важных возможностей устройства Android. Это разрешение следует использовать с осторожностью, так как оно может привести к несовместимости, нестабильности и неработоспособности компонентов приложения."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"выбирать предпочтительные приложения"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Позволяет приложению изменять предпочтительные приложения. Вредоносные приложения могут использовать эту возможность для незаметного изменения запущенных приложений и для сбора конфиденциальной информации с помощью имитации подключения существующих приложений."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"изменять общие настройки системы"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Позволяет приложению управлять вспышкой."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"доступ к USB-устройствам"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Позволяет приложению получать доступ к USB-устройствам."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"Реализовать протокол MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Разрешает доступ к драйверу основного устройства MTP для реализации протокола MTP USB"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"проверять аппаратное обеспечение"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Позволяет приложению управлять различными периферийными устройствами для проверки аппаратного обеспечения."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"посылать прямые вызовы на номера телефонов"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"изменять/удалять содержимое SD-карты"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Разрешает приложению запись на USB-накопитель."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Разрешает приложению запись на SD-карту"</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"изм./удал. содерж. мультимедиа"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Позволяет приложению изменять содержание внутреннего хранилища мультимедиа."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"получать доступ к кэшу файловой системы"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Разрешает программам доступ для записи и чтения к кэшу файловой системы."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"совершать и принимать интернет-вызовы"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Настройте глобальный прокси-сервер устройства, который будет использоваться при активной политике. Глобальный прокси-сервер должен настроить первый администратор устройства."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Задать время действия пароля"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Задать время действия пароля перед появлением экрана блокировки"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Настроить шифрование хранилища"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Требует шифровать данные приложений, находящиеся в хранилище."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Домашний"</item>
<item msgid="869923650527136615">"Мобильный"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Рабочий"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Другой"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Введите PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Нажмите для ввода пароля"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Введите пароль для разблокировки"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Введите PIN-код для разблокировки"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Неверный PIN-код!"</string>
@@ -613,7 +612,7 @@
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Экран заблокирован."</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Нажмите \"Меню\", чтобы разблокировать экран или вызвать службу экстренной помощи."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Для разблокировки нажмите \"Меню\"."</string>
- <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Для разблокировки введите графический ключ"</string>
+ <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Введите графический ключ"</string>
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Экстренный вызов"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Вернуться к вызову"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Правильно!"</string>
@@ -627,7 +626,7 @@
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"SIM-карта не установлена."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"SIM-карта не установлена."</string>
<string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Вставьте SIM-карту."</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"Только экстренный вызов"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Только экстренные вызовы"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Сеть заблокирована"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карта заблокирована с помощью кода PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="635967534992394321">"См. руководство пользователя или свяжитесь со службой поддержки."</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Пароль"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Вход"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Неверное имя пользователя или пароль."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Забыли имя пользователя или пароль?"\n"Перейдите на страницу "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Проверка..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Разблокировать"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Вкл. звук"</string>
@@ -665,14 +665,12 @@
<string name="js_dialog_before_unload" msgid="1901675448179653089">"Перейти с этой страницы?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Нажмите \"ОК\", чтобы продолжить, или \"Отмена\", чтобы остаться на текущей странице."</string>
<string name="save_password_label" msgid="6860261758665825069">"Подтвердите"</string>
<string name="double_tap_toast" msgid="1068216937244567247">"Совет: нажмите дважды, чтобы увеличить и уменьшить масштаб."</string>
- <string name="autofill_this_form" msgid="1272247532604569872">"Автозап."</string>
+ <string name="autofill_this_form" msgid="1272247532604569872">"Автозаполнение"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Нужна настройка"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"считывать историю и закладки браузера"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Разрешает приложению считывать все URL, посещенные браузером, и все его закладки."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"записывать историю и закладки браузера"</string>
@@ -688,7 +686,7 @@
<string name="save_password_never" msgid="8274330296785855105">"Никогда"</string>
<string name="open_permission_deny" msgid="5661861460947222274">"У вас нет разрешения на открытие этой страницы."</string>
<string name="text_copied" msgid="4985729524670131385">"Текст скопирован в буфер обмена."</string>
- <string name="more_item_label" msgid="4650918923083320495">"Дополнительно"</string>
+ <string name="more_item_label" msgid="4650918923083320495">"Ещё"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Меню+"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"пробел"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"ввод"</string>
@@ -846,8 +844,8 @@
<string name="volume_music" msgid="5421651157138628171">"Громкость мультимедиа"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Воспроизведение по каналу Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Выбран режим \"Без звука\""</string>
- <string name="volume_call" msgid="3941680041282788711">"Громкость входящего вызова"</string>
- <string name="volume_bluetooth_call" msgid="2002891926351151534">"Громкость входящего вызова Bluetooth"</string>
+ <string name="volume_call" msgid="3941680041282788711">"Громкость при разговоре"</string>
+ <string name="volume_bluetooth_call" msgid="2002891926351151534">"Громкость при разговоре"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Громкость сигнала предупреждения"</string>
<string name="volume_notification" msgid="2422265656744276715">"Громкость уведомления"</string>
<string name="volume_unknown" msgid="1400219669770445902">"Громкость"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Выберите способ ввода"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Настроить способ ввода"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string>
@@ -960,17 +959,17 @@
<string name="sync_binding_label" msgid="3687969138375092423">"Синхр."</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Спец. возможности"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновый рисунок"</string>
- <string name="chooser_wallpaper" msgid="7873476199295190279">"Изменить фоновый рисунок"</string>
+ <string name="chooser_wallpaper" msgid="7873476199295190279">"Сменить обои"</string>
<string name="pptp_vpn_description" msgid="2688045385181439401">"Протокол PPTP"</string>
<string name="l2tp_vpn_description" msgid="3750692169378923304">"Протокол L2TP"</string>
- <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN (на основе предв. общ. ключа)"</string>
- <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN (на основе сертификата)"</string>
+ <string name="l2tp_ipsec_psk_vpn_description" msgid="3945043564008303239">"L2TP/IPSec VPN с использованием общего ключа"</string>
+ <string name="l2tp_ipsec_crt_vpn_description" msgid="5382714073103653577">"L2TP/IPSec VPN с использованием сертификатов"</string>
<string name="upload_file" msgid="2897957172366730416">"Выбрать файл"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Не выбран файл"</string>
<string name="reset" msgid="2448168080964209908">"Сбросить"</string>
<string name="submit" msgid="1602335572089911941">"Отправить"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Режим громкой связи включен"</string>
- <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Выберите для выхода из режима громкой связи."</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Включен режим \"Штурман\""</string>
+ <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Чтобы закрыть приложение, нажмите здесь."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"USB-модем или точка доступа Wi-Fi активны"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"Нажмите для настройки"</string>
<string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 совпадение"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> из <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Готово"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Отключение USB-накопителя..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Отключение SD-карты..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Очистка USB-накопителя..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Отправить"</string>
<string name="find" msgid="4808270900322985960">"Найти"</string>
<string name="websearch" msgid="4337157977400211589">"Веб-поиск"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Пользователь <xliff:g id="NAME">%s</xliff:g> запрашивает ваше местоположение"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Запрос местоположения"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Запрашивает <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Да"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Нет"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Превышен предел удаления"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Удаленных объектов для <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>, аккаунт <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Что нужно сделать?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Удалить элементы."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Отменить удаления."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Ничего не делать сейчас."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) подключена"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) отключена"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Нажмите для повторного подключения к VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Выберите аккаунт"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличить"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Уменьшить"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 397688d..0895aa1 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Režim V lietadle"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V lietadle je ZAPNUTÝ"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V lietadle je VYPNUTÝ"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Spoplatnené služby"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania metódy vstupu. Bežné aplikácie by toto nastavenie nemali vôbec využívať."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"väzba na tapetu"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tapety. Bežné aplikácie by toto nastavenie vôbec nemali využívať."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"viazať sa k službe miniaplikácie"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby miniaplikácie. Bežné aplikácie by toto nastavenie vôbec nemali používať."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"komunikovať so správcom zariadenia"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Umožňuje držiteľovi odosielať informácie správcovi zariadenia. Bežné aplikácie by toto oprávnenie nemali nikdy požadovať."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"zmena orientácie obrazovky"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Umožňuje aplikácii ovládať kontrolku."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"prístup k zariadeniam USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Umožní aplikácii prístup k zariadeniam USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementovať protokol MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Povoľuje prístup k ovládaču kernel MTP na implementáciu protokolu MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testovanie hardvéru"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Umožňuje aplikácii ovládať rôzne periférie na účely testovania hardvéru."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"priame volanie na telefónne čísla"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globálny server proxy, ktorý sa bude používať po aktivácii pravidiel. Platný globálny server proxy nastavuje iba prvý správca zariadenia."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastav. koniec platnosti hesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládanie doby, po uplynutí ktorej treba zmeniť heslo na odomknutie obrazovky"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastaviť šifr. ukl. priestoru"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Vyžaduje šifrovanie uložených údajov aplikácií"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domovská stránka"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Práca"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Iné"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Zadajte kód PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Po dotyku môžete zadať heslo"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Zadajte heslo pre odomknutie"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Zadajte kód PIN pre odomknutie"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Nesprávny kód PIN"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Heslo"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prihlásiť sa"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neplatné používateľské meno alebo heslo."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Zabudli ste používateľské meno alebo heslo?"\n"navštívte stránky "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Prebieha kontrola..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odomknúť"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zapnúť zvuk"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez rozhranie USB pripojené"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Výber metódy vstupu"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurovať metódy vstupu"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Zdieľať"</string>
<string name="find" msgid="4808270900322985960">"Nájsť"</string>
<string name="websearch" msgid="4337157977400211589">"Hľadať na webe"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Žiadosť o informácie o polohe od používateľa <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Žiadosť o informácie o polohe"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Žiadosť od používateľa <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Áno"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nie"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Bol prekročený limit odstraňovania"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Odstránené položky: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Typ synchronizácie: <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>. Účet: <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Akú akciu chcete vykonať?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Odstrániť položky."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Vrátiť späť odstránenia."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Nevykonať akciu."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je pripojená"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojená"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Dotykom sa znova pripojíte k sieti VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Vybrať účet"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšenie"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zníženie"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 91c42a8..486e266 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Način za letalo"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Način za letalo je VKLOPLJEN"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Način za letalo je IZKLOPLJEN"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100 +"</string>
<string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Plačljive storitve"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Dovoljuje lastniku, da se poveže z vmesnikom načina vnosa najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"povezovanje z ozadjem"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Dovoljuje, da se lastnik poveže z vmesnikom ozadja najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"poveži s storitvijo pripomočka"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Lastniku omogoči povezovanje z vmesnikom storitve pripomočka najvišje ravni. Ne uporabljajte za navadne programe."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interakcija s skrbnikom naprave"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Dovoljuje lastniku, da pošlje namere skrbniku naprave. Nikoli se ne uporablja za navadne programe."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"spreminjanje usmerjenosti zaslona"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Programu dovoljuje nadzor svetilke."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"dostop do naprav USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Programu omogoča dostop do naprav USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"uveljavitev protokola MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Omogoča dostop do gonilnika jedra MTP za uveljavitev protokola MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"preskušanje strojne opreme"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Programu dovoljuje nadzor različnih zunanjih naprav za preskušanje strojne opreme."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"neposredno klicanje telefonskih številk"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nastavite globalni strežnik proxy naprave, ki bo v uporabi, ko je pravilnik omogočen. Samo skrbnik prve naprave lahko nastavi veljaven globalni strežnik proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavitev poteka gesla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Nastavite, koliko časa prej je treba spremeniti geslo za odklepanje zaslona"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Nastavitev šifriranja shrambe"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Shranjeni podatki programa morajo biti šifrirani"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Začetna stran"</item>
<item msgid="869923650527136615">"Mobilni"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Služba"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Vnesite kodo PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Dotaknite se za vnos gesla"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Vnesite geslo za odklop"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Vnesite PIN za odklepanje"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Nepravilna koda PIN."</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Geslo"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prijava"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Neveljavno uporabniško ime ali geslo."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Ste pozabili uporabniško ime ali geslo?"\n"Obiščite "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Preverjanje ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Odkleni"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Vklopi zvok"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"iskanje in odpravljanje napak USB je povezano"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Izbiranje načina vnosa"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Nastavitev načinov vnosa"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -997,26 +1001,21 @@
<string name="media_unknown_state" msgid="729192782197290385">"Neznano stanje zunanjih nosilcev podatkov."</string>
<string name="share" msgid="1778686618230011964">"Deli z dr."</string>
<string name="find" msgid="4808270900322985960">"Najdi"</string>
- <!-- no translation found for websearch (4337157977400211589) -->
- <skip />
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="websearch" msgid="4337157977400211589">"Spletno iskanje"</string>
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Zahteva za lokacijo uporabnika <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahteva za lokacijo"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Zahtevala oseba <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Omejitev brisanja je presežena"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Izbrisanih je bilo <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> elementov za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> v računu <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Kaj želite narediti?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Izbriši elemente."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Razveljavi brisanje."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Zaenkrat ne naredi ničesar."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Povezava z navideznim zasebnim omrežjem <xliff:g id="PROFILENAME">%s</xliff:g> je vzpostavljena"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Povezava z navideznim zasebnim omrežjem <xliff:g id="PROFILENAME">%s</xliff:g> prekinjena"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Dotaknite se, če želite znova vzpostaviti povezavo z navideznim zasebnim omrežjem."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Izberite račun"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Povečaj"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmanjšaj"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c5c1e43..aebd8e2 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Режим рада у авиону"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим рада у авиону је УКЉУЧЕН"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим рада у авиону је ИСКЉУЧЕН"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Услуге које се плаћају"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Омогућава власнику да се обавеже на интерфејс методе уноса највишег нивоа. Обичне апликације никада не би требало да је користе."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"обавезивање на позадину"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Омогућава власнику да се обавеже на интерфејс позадине највишег нивоа. Обичне апликације никада не би требало да је користе."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обавезивање на услугу виџета"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Омогућава власнику да се обавеже на интерфејс услуге виџета највишег нивоа. За обичне апликације ово никада не би требало да буде потребно."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"интеракција са администратором уређаја"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Омогућава власнику да шаље своје намере администратору уређаја. Обичне апликације никада не би требало да је користе."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"промена положаја екрана"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Омогућава да апликација контролише осветљење."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"приступ USB уређајима"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Омогућава апликацији приступ USB уређајима."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"примени MTP протокол"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Омогућава приступ основном MTP управљачком програму ради примене MTP USB протокола."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"тестирање хардвера"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Омогућава да апликација контролише разноврсне периферне уређаје у сврхе тестирања хардвера."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"директно позивање бројева телефона"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Подесите глобални прокси сервер уређаја који ће се користити док су омогућене смернице. Само први администратор уређаја поставља ефективни глобални прокси сервер."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Подеси време истека лозинке"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролишите време када лозинка за закључавање екрана треба да се промени"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Подешавање шифровања складишта"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Захтева да сачувани подаци апликације буду шифровани"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Кућа"</item>
<item msgid="869923650527136615">"Мобилни"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Посао"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Други"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Унесите PIN кôд"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Додирните за унос лозинке"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Унесите лозинку за откључавање"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Унесите PIN да бисте откључали тастатуру"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN кôд је нетачан!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Лозинка"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Пријави ме"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Неважеће корисничко име или лозинка."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Заборавили сте корисничко име или лозинку?"\n"Посетите"<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Проверавање..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Откључај"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Укључи звук"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
<string name="select_input_method" msgid="6865512749462072765">"Избор методе уноса"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Конфигуриши методе уноса"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -981,7 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 подударање"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> од <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <string name="action_mode_done" msgid="7217581640461922289">"Done"</string>
+ <string name="action_mode_done" msgid="7217581640461922289">"Готово"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Искључивање USB меморије..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"У току је искључивање SD картице..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Брисање USB меморије је у току..."</string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Дели"</string>
<string name="find" msgid="4808270900322985960">"Пронађи"</string>
<string name="websearch" msgid="4337157977400211589">"Веб претрага"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Захтев за локацију од корисника <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Захтев за локацију"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Захтева <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Да"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Не"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Премашено је ограничење за брисање"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Број избрисаних ставки за <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, налог <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> је <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Шта желите да урадите?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Избриши ставке."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Опозови брисања."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Не ради ништа за сада."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је успостављена"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је прекинута"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Додирните да бисте се поново повезали са VPN-ом."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Избор налога"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Повећање"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Смањење"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index bda3863..296c2a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Avslutar…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din pekdator stängs av."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon stängs av."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Vill du stänga av?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Inga nya program."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Alternativ för pekdatorn"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Flygplansläge"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Flygplansläge är AKTIVERAT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Flygplansläge är INAKTIVERAT"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">">100"</string>
<string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjänster som kostar pengar"</string>
@@ -202,11 +200,11 @@
<string name="permdesc_writeSms" product="default" msgid="6299398896177548095">"Tillåter att program skriver till SMS-meddelanden som lagrats på din telefon eller SIM-kort. Skadliga program kan radera dina meddelanden."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"ta emot WAP"</string>
<string name="permdesc_receiveWapPush" msgid="5979623826128082171">"Tillåter att program tar emot och bearbetar WAP-meddelanden. Skadliga program kan övervaka dina meddelanden eller ta bort dem utan att visa dem för dig."</string>
- <string name="permlab_getTasks" msgid="5005277531132573353">"hämta program som körs"</string>
+ <string name="permlab_getTasks" msgid="5005277531132573353">"hämta appar som körs"</string>
<string name="permdesc_getTasks" msgid="7048711358713443341">"Tillåter att program hämtar information om uppgifter som körs och har körts. Skadliga program kan upptäcka privat information om andra program."</string>
<string name="permlab_reorderTasks" msgid="5669588525059921549">"byt ordning på program som körs"</string>
<string name="permdesc_reorderTasks" msgid="126252774270522835">"Tillåter att ett program flyttar uppgifter till förgrunden eller bakgrunden. Skadliga program kan tvinga sig till förgrunden utan att du kan styra det."</string>
- <string name="permlab_setDebugApp" msgid="4339730312925176742">"aktivera felsökning av program"</string>
+ <string name="permlab_setDebugApp" msgid="4339730312925176742">"aktivera felsökning av appar"</string>
<string name="permdesc_setDebugApp" msgid="5584310661711990702">"Tillåter att ett program aktiverar felsökning för ett annat program. Skadliga program kan använda detta för att avsluta andra program."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"ändra dina gränssnittsinställningar"</string>
<string name="permdesc_changeConfiguration" msgid="3465121501528064399">"Tillåter att ett program ändrar den aktuella konfigurationen, till exempel språk eller övergripande teckenformat."</string>
@@ -257,15 +255,17 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en inmatningsmetod. Ska inte behövas för vanliga program."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"binda till en bakgrund"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en bakgrund. Ska inte behövas för vanliga program."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind till en widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en widget. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"arbeta med en enhetsadministratör"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Tillåter att innehavaren skickar avsikter till en enhetsadministratör. Vanliga program behöver aldrig göra detta."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ändra bildskärmens rikting"</string>
<string name="permdesc_setOrientation" msgid="6335814461615851863">"Tillåter att ett program när som helst ändrar skärmens rotering. Behövs inte för vanliga program."</string>
- <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"skicka Linux-signaler till program"</string>
+ <string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"skicka Linux-signaler till appar"</string>
<string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"Tillåter att programmet begär att den angivna signalen skickas till alla beständiga processer."</string>
<string name="permlab_persistentActivity" msgid="8659652042401085862">"se till att programmet alltid körs"</string>
<string name="permdesc_persistentActivity" msgid="5037199778265006008">"Tillåter att ett program gör vissa delar beständiga så att systemet inte kan använda det för andra program."</string>
- <string name="permlab_deletePackages" msgid="3343439331576348805">"ta bort program"</string>
+ <string name="permlab_deletePackages" msgid="3343439331576348805">"ta bort appar"</string>
<string name="permdesc_deletePackages" msgid="3634943677518723314">"Tillåter att ett program tar bort Android-paket. Skadliga program kan använda detta för att ta bort viktiga program."</string>
<string name="permlab_clearAppUserData" msgid="2192134353540277878">"ta bort de andra programmens uppgifter"</string>
<string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Tillåter att ett program tar bort användardata."</string>
@@ -275,7 +275,7 @@
<string name="permdesc_getPackageSize" msgid="5557253039670753437">"Tillåter att ett program hämtar kod, data och cachestorlekar"</string>
<string name="permlab_installPackages" msgid="335800214119051089">"installera program direkt"</string>
<string name="permdesc_installPackages" msgid="526669220850066132">"Tillåter att ett program installerar nya eller uppdaterade Android-paket. Skadliga program kan använda detta för att lägga till nya program med godtyckliga och starka behörigheter."</string>
- <string name="permlab_clearAppCache" msgid="4747698311163766540">"ta bort cacheinformation för alla program"</string>
+ <string name="permlab_clearAppCache" msgid="4747698311163766540">"ta bort cacheinformation för alla appar"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="3097119797652477973">"Tillåter att ett program frigör lagringsutrymme på pekdatorn genom att ta bort filer i programmets katalog för cachelagring. Mycket begränsad åtkomst, vanligtvis till systemprocesser."</string>
<string name="permdesc_clearAppCache" product="default" msgid="7740465694193671402">"Tillåter att ett program frigör lagringsutrymme i telefonen genom att ta bort filer i programmets katalog för cachelagring. Åtkomst är mycket begränsad, vanligtvis till systemprocesser."</string>
<string name="permlab_movePackage" msgid="728454979946503926">"Flytta programresurser"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Tillåter att ett program läser och skriver till en resurs som ägs av diag-gruppen; till exempel filer i /dev. Detta kan eventuellt påverka systemets stabilitet och säkerhet. Detta bör ENDAST används av tillverkaren eller operatören för maskinvaruspecifik diagnostik."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"aktivera eller inaktivera programkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Tillåter att ett program ändrar inställningen för om en komponent i ett annat program har aktiverats eller inte. Skadliga program kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Tillåter att ett program ändrar inställningen för om en komponent i ett annat program har aktiverats eller inte. Skadliga program kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Tillåter att en app ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i telefonen. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ange önskade program"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Tillåter att ett program ändrar dina önskade program. Skadliga program kan utan varning ändra de program som körs och förfalska dina befintliga program så att de samlar privata data från dig."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"ändra globala systeminställningar"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Tillåter att programmet styr lampan."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"åtkomst till USB-enheter"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Tillåter att programmet använder USB-enheter."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"implementera MTP-protokoll"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Ger åtkomst till MTP-kerneldrivrutinen för att implementera MTP/USB-protokollet."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"testa maskinvara"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Tillåter att ett program styr kringutrustning i syfte att testa maskinvara."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"ringa telefonnummer direkt"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ändra/ta bort innehåll på SD-kortet"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Får skriva till USB-enheten."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Tillåter att ett program skriver till SD-kortet."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ändra/ta bort innehåll"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Tillåter att en app ändrar innehållet på den interna lagringsenheten."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"åtkomst till cachefilsystemet"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Tillåter att ett program läser och skriver till cachefilsystemet."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"ringa/ta emot Internetsamtal"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ange vilken global proxyserver som ska användas när policyn är aktiverad. Endast den första enhetsadministratören anger den faktiska globala proxyservern."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Ange lösenordets utgångsdatum"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ange krypterad lagring"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Kräv att sparade applikationsdata krypteras."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbete"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Övrigt"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Ange PIN-kod"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Tryck om du vill ange lösenord"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Ange lösenord för att låsa upp"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Ange PIN-kod för att låsa upp"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Fel PIN-kod!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Lösenord"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logga in"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Ogiltigt användarnamn eller lösenord."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Har du glömt ditt användarnamn eller lösenord?"\n"Besök "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollerar ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Lås upp"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Ljud på"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"Autofyll"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Konfig. Autofyll"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"läsa webbläsarhistorik och bokmärken"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Tillåter att program läser alla webbadresser som webbläsaren har öppnat och alla webbläsarens bokmärken."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skriva webbläsarhistorik och bokmärken"</string>
@@ -814,7 +812,7 @@
<string name="capital_off" msgid="6815870386972805832">"AV"</string>
<string name="whichApplication" msgid="4533185947064773386">"Slutför åtgärd genom att använda"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Använd som standard för denna åtgärd."</string>
- <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Rensa standardinställning i Startinställningar > Program > Hantera program."</string>
+ <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Rensa standardinställning i Startinställningar > Appar > Hantera appar."</string>
<string name="chooseActivity" msgid="1009246475582238425">"Välj en åtgärd"</string>
<string name="noApplications" msgid="1691104391758345586">"Inga program kan utföra den här åtgärden."</string>
<string name="aerr_title" msgid="653922989522758100">"Tyvärr!"</string>
@@ -865,7 +863,7 @@
<item quantity="other" msgid="7915895323644292768">"Öppna Wi-Fi-nätverk är tillgängliga"</item>
</plurals>
<string name="select_character" msgid="3365550120617701745">"Infoga tecken"</string>
- <string name="sms_control_default_app_name" msgid="7630529934366549163">"Okänt program"</string>
+ <string name="sms_control_default_app_name" msgid="7630529934366549163">"Okänd app"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Skickar SMS"</string>
<string name="sms_control_message" msgid="1289331457999236205">"Flera SMS-meddelanden skickas. Tryck på OK om du vill fortsätta eller på Avbryt om du vill avsluta sändningen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
<string name="select_input_method" msgid="6865512749462072765">"Välj indatametod"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Konfigurera inmatningsmetoder"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 träff"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> av <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Klar"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Demontera USB-lagringsenhet..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"Demonterar SD-kort..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Raderar USB-lagring..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Dela"</string>
<string name="find" msgid="4808270900322985960">"Sök efter"</string>
<string name="websearch" msgid="4337157977400211589">"Webbsökning"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Positionsförfrågan från <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Positionsförfrågan"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Begärt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Nej"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Gränsen för borttagning har överskridits"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Det finns <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> borttagna objekt för <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Vad vill du göra?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Ta bort objekten."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Ångra borttagningarna."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Gör ingenting just nu."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN anslutet"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN frånkopplat"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Tryck här om du vill återansluta till ett VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Välj ett konto"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Öka"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Minska"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 41593f2..ce9e131 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"โหมดใช้งานบนเครื่องบิน"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"เปิดโหมดใช้งานบนเครื่องบิน"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"โหมดใช้งานบนเครื่องบินปิดทำงานอยู่"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
<string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"บริการที่ต้องเสียค่าใช้จ่าย"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"อนุญาตให้ผู้ถือเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของวิธีป้อนข้อมูล ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"เชื่อมโยงกับวอลเปเปอร์"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"อนุญาตให้ผู้ถือเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของวอลเปเปอร์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"เชื่อมโยงกับบริการวิดเจ็ต"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"อนุญาตให้เจ้าของเชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการวิดเจ็ต ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ติดต่อกับผู้ดูแลอุปกรณ์"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"อนุญาตให้ผู้ถือส่งเนื้อหาไปยังโปรแกรมควบคุมอุปกรณ์ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"เปลี่ยนการวางแนวหน้าจอ"</string>
@@ -286,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังรีซอร์สที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"เปิดหรือปิดการใช้งานส่วนประกอบของแอปพลิเคชัน"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"อนุญาตให้แอปพลิเคชันเปลี่ยนว่าจะเปิดการใช้งานคอมโพเนนต์หรือแอปพลิเคชันอื่นหรือไม่ แอปพลิเคชันที่เป็นอันตรายอาจใช้วิธีนี้เพื่อปิดการใช้งานคุณสมบัติที่สำคัญของแท็บเล็ตได้ ต้องใช้ความระมัดระวังเกี่ยวกับการอนุญาตนี้เพราะอาจทำให้คอมโพเนนต์ของแอปพลิเคชันเข้าสู่สถานะที่ไม่สามารถใช้งานได้ ไม่คงที่ หรือไม่เสถียร"</string>
- <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"อนุญาตให้แอปพลิเคชันเปลี่ยนว่าจะเปิดใช้งานส่วนประกอบหรือแอปพลิเคชันอื่นหรือไม่ แอปพลิเคชันที่เป็นอันตรายอาจใช้วิธีนี้เพื่อปิดการใช้งานคุณสมบัติที่สำคัญของโทรศัพท์ได้ การอนุญาตจึงต้องทำอย่างระมัดระวัง เพราะอาจทำให้ส่วนประกอบของแอปพลิเคชันอยู่ในสถานะใช้งานไม่ได้ ทำงานไม่คงที่ หรือไม่เสถียรได้"</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"อนุญาตให้แอปพลิเคชันเปลี่ยนว่าจะเปิดใช้งานส่วนประกอบหรือแอปพลิเคชันอื่นหรือไม่ แอปพลิเคชันที่เป็นอันตรายอาจใช้วิธีนี้เพื่อปิดการใช้งานคุณสมบัติที่สำคัญของโทรศัพท์ได้ การอนุญาตจึงต้องทำอย่างระมัดระวัง เพราะอาจทำให้ส่วนประกอบของแอปพลิเคชันอยู่ในสถานะใช้งานไม่ได้ ทำงานไม่คงที่ หรือไม่เสถียร"</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"ตั้งค่าแอปพลิเคชันที่เหมาะสม"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"อนุญาตให้แอปพลิเคชันแก้ไขแอปพลิเคชันที่คุณต้องการ วิธีนี้อาจทำให้แอปพลิเคชันที่เป็นอันตรายแอบเปลี่ยนแอปพลิเคชันที่มีการเรียกใช้งาน โดยการปลอมแปลงแอปพลิเคชันที่มีอยู่ของคุณเพื่อเก็บข้อมูลส่วนบุคคลจากคุณ"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"แก้ไขการตั้งค่าระบบสากล"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"อนุญาตให้แอปพลิเคชันควบคุมไฟฉาย"</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"เข้าถึงอุปกรณ์ USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"อนุญาตให้แอปพลิเคชันเข้าถึงอุปกรณ์ USB"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"ใช้โปรโตคอล MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"อนุญาตการเข้าถึงไดรเวอร์ Kernel MTP เพื่อใช้โปรโตคอล MTP USB"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"ทดสอบฮาร์ดแวร์"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"อนุญาตให้แอปพลิเคชันควบคุมอุปกรณ์ต่อพ่วงหลายอย่างเพื่อการทดสอบฮาร์ดแวร์"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"โทรติดต่อหมายเลขโทรศัพท์โดยตรง"</string>
@@ -465,7 +464,7 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"แก้ไข/ลบข้อมูลการ์ด SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"อนุญาตให้แอปพลิเคชันเขียนไปยังที่เก็บข้อมูล USB"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"อนุญาตให้แอปพลิเคชันเขียนลงบนการ์ด SD"</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"แก้ไข/ลบเนื้อหาของที่เก็บข้อมูลสื่อภายใน"</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"แก้/ลบเนื้อหาข้อมูลสื่อภายใน"</string>
<string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"อนุญาตให้แอปพลิเคชันแก้ไขเนื้อหาของที่เก็บข้อมูลสื่อภายใน"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"เข้าถึงระบบไฟล์แคช"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"อนุญาตให้แอปพลิเคชันอ่านและเขียนระบบไฟล์แคช"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ตั้งค่าพร็อกซีส่วนกลางของอุปกรณ์ที่จะใช้ขณะเปิดการใช้งานนโยบาย เฉพาะผู้ดูแลอุปกรณ์คนแรกเท่านั้นที่ตั้งค่าพร็อกซีส่วนกลางที่มีผลบังคับ"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"ตั้งค่าการหมดอายุของรหัสผ่าน"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"ควบคุมระยะเวลาก่อนที่จะต้องเปลี่ยนรหัสผ่านการล็อกหน้าจอ"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"ตั้งค่าการเข้ารหัสที่เก็บข้อมูล"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"กำหนดว่าแอปพลิเคชันที่จัดเก็บต้องมีการเข้ารหัส"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"บ้าน"</item>
<item msgid="869923650527136615">"มือถือ"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"ที่ทำงาน"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"อื่นๆ"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"ป้อนรหัส PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"แตะเพื่อใส่รหัสผ่าน"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"ป้อนรหัสผ่านเพื่อปลดล็อก"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"ป้อน PIN เพื่อปลดล็อก"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"รหัส PIN ไม่ถูกต้อง!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"รหัสผ่าน"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ลงชื่อเข้าใช้"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง"</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"หากลืมชื่อผู้ใช้หรือรหัสผ่าน"\n"โปรดไปที่ "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"กำลังตรวจสอบ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"ปลดล็อก"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"เปิดเสียง"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
<string name="select_input_method" msgid="6865512749462072765">"เลือกวิธีป้อนข้อมูล"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"กำหนดค่าวิธีการป้อนข้อมูล"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"แบ่งปัน"</string>
<string name="find" msgid="4808270900322985960">"ค้นหา"</string>
<string name="websearch" msgid="4337157977400211589">"ค้นเว็บ"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"คำขอสถานที่จาก <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"คำขอสถานที่"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"ร้องขอโดย <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"ใช่"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"ไม่"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"เกินจำนวนการลบสูงสุด"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"พบรายการที่ถูกลบ <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> รายการสำหรับ <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> บัญชี <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> คุณต้องการทำอะไร"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"ลบรายการ"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"เลิกทำการลบ"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"ไม่ต้องทำอะไรในขณะนี้"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> เชื่อมต่อ VPN แล้ว"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> ตัดการเชื่อมต่อ VPN แล้ว"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"แตะเพื่อเชื่อมต่อกับ VPN อีกครั้ง"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"เลือกบัญชี"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"การเพิ่ม"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"การลด"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f65d77e..c26d789 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Airplane mode"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Naka-ON ang airplane mode"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Naka-OFF ang airplane mode"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Mga serbisyong ginagastusan mo"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pinapayagan ang holder na sumailalim sa nangungunang antas na interface ng pamamaraan ng pag-input. Hindi dapat kailanmang kailanganin para sa mga normal na application."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sumailalim sa wallpaper"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Pinapayagan ang holder na sumailalim sa interface na nasa nangungunang antas ng wallpaper. Hindi kailanman dapat na kailanganin para sa mga normal na application."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"itali sa serbisyo ng widget"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Pinapayagan ang may-hawak na matali sa interface ng tuktok sa antas ng serbisyo ng widget. Hindi dapat kailanganin para sa mga normal na application."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"makipag-ugnay sa tagapangasiwa ng device"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Pinapayagan ang holder na magpadala ng mga intensyon sa administrator ng device. Hindi kailanman dapat kailanganin para sa mga normal na application."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"baguhin ang orientation ng screen"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Pinapayagan ang application na kontrolin ang flashlight."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"i-access ang mga USB device"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Pinapayagan ang application na i-access ang mga USB device."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"ipatupad ang MTP protocol"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Pinapayagan ang access sa kernel MTP driver upang maipatupad ang MTP USB protocol."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"subukan ang hardware"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Pinapayagan ang application na kontrolin ang iba\'t ibang peripheral para sa layunin ng pagsubok ng hardware."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"direktang tawagan ang mga numero ng telepono"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Itakda ang pandaigdigang proxy ng device na gagamitin habang pinagana ang patakaran. Tanging ang unang admin ng device ang magtatakda sa may bisang pandaigdigang proxy."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Itakda pag-expire ng password"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolin kung gaano katagal bago kailangang palitan ang password sa pag-lock ng screen"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Itakda pag-encrypt ng imbakan"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Hinging naka-encrypt ang nakaimbak na data ng application"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Home"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabaho"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Iba pa"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Ipasok ang PIN code"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"I-touch pra mg-passwrd"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Ipasok ang password upang i-unlock"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Ipasok ang PIN upang i-unlock"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Maling PIN code!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Password"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Mag-sign in"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Di-wastong username o password."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Nakalimutan ang iyong username o password?"\n"Bisitahin ang "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Sinusuri..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"I-unlock"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"I-on ang tunog"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Piliin upang huwag paganahin ang debugging ng USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Pumili ng pamamaraan ng pag-input"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"I-configure paraan ng input"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"mga kandidato"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Ibahagi"</string>
<string name="find" msgid="4808270900322985960">"Hanapin"</string>
<string name="websearch" msgid="4337157977400211589">"Paghahanap sa Web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Kahilingan sa lokasyon mula kay <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Kahilingan sa Lokasyon"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Hiniling ni <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Oo"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Hindi"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Nalagpasan na ang limitasyon sa pagtanggal"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Mayroong <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> (na) natanggal na item para sa <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, account na <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Ano ang gusto mong gawin?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Tanggalin ang mga item."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"I-undo ang mga pagtanggal."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Walang gawin sa ngayon."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Nakakonekta ang <xliff:g id="PROFILENAME">%s</xliff:g> sa VPN"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Hindi nakakonekta ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Pindutin upang muling kumonekta sa VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Pumili ng account"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Taasan"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Babaan"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 762ea47..08e4e71 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Kapanıyor…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tabletiniz kapanacak."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefonunuz kapanacak."</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"Kapatmak istiyor musunuz?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"Hiçbir yeni uygulama yok."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Tablet seçenekleri"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Uçak modu"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uçak modu AÇIK"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Uçak modu KAPALI"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Size maliyet getiren hizmetler"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Tutucunun bir giriş yönteminin en üst düzey arayüzüne bağlanmasına izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"bir duvar kağıdına tabi kıl"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Hesap sahibine bir duvar kağıdının en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bir widget hizmetine bağla"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Hesap sahibine bir widget hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"bir cihaz yöneticisi ile etkileşimde bulun"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Cihazın sahibinin cihaz yöneticisine amaç göndermesine izin verir. Normal uygulamalarda hiçbir zaman gerek duyulmamalıdır."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"ekran yönünü değiştir"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Uygulamanın tanılama grubundaki bir kaynağa ait herhangi bir kaynağı; örneğin /dev içindeki dosyaları okumasına ve bunlara yazmasına izin verir. Bu işlevin sistem kararlılığını ve güvenliğini olumsuz etkileme olasılığı vardır. Üretici veya operatör tarafından YALNIZCA donanıma özgü tanılama için kullanılmalıdır."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Uygulamaya başka bir uygulamanın bir bileşenini etkinleştirme ayarını değiştirme izni verir. Kötü amaçlı uygulamalar bu ayarı tabletin önemli yeteneklerini devre dışı bırakmak için kullanabilir. Bu iznin verilmesi uygulama bileşenlerini kullanılamaz, tutarsız veya kararsız bir duruma sokabileceği için izin verilirken dikkatli olunmalıdır."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Uygulamaya başka bir uygulamanın bir bileşenini etkinleştirme ayarını değiştirme izni verir. Kötü amaçlı uygulamalar bu ayarı tabletin önemli yeteneklerini devre dışı bırakmak için kullanabilir. Bu iznin verilmesi uygulama bileşenlerini kullanılamaz, tutarsız veya kararsız bir duruma sokabileceği için izin verilirken dikkatli olunmalıdır."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Uygulamaya, başka bir uygulamanın bir bileşenini etkinleştirme ayarını değiştirme izni verir. Kötü amaçlı uygulamalar bu ayarı telefonun önemli yeteneklerini devre dışı bırakmak için kullanabilir. Bu iznin verilmesi uygulama bileşenlerini kullanılamaz, tutarsız veya kararsız bir duruma sokabileceği için izin verilirken dikkatli olunmalıdır."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"tercih edilen uygulamaları ayarla"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Uygulamanın tercih ettiğiniz uygulamaları değiştirmesine izin verir. Bu işlem, kötü amaçlı uygulamaların, çalışmakta olan uygulamaları sessizce değiştirerek mevcut uygulamalarınızı aldatıp kişisel bilgilerinizi almasına izin verebilir."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"genel sistem ayarlarını değiştir"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Uygulamaların flaş ışığını denetlemesine izin verir."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"USB cihazlarına erişme"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Uygulamaların USB cihazlarına erişimine izin verir"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"MTP protokolünü uygula"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"MTP USB protokolünü uygulamak için çekirdekteki MTP sürücüsüne erişim izni ver."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"donanımı test et"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Uygulamanın donanım testi için çeşitli çevre birimlerini denetlemesine izin verir."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"telefon numaralarına doğrudan çağrı yap"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"SD kart içeriklerini değiştir/sil"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Uygulamanın USB dep birimine yazmasına izni verir."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Bir uygulamaya SD karta yazma izni verir."</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"önbellek dosya sistemine eriş"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Bir uygulamanın önbellek dosya sisteminde okuma yazma yapmasına izin verir."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"İnternet çağrılar yap/alma"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Politika etkin olduğunda kullanılacak cihaz genelinde geçerli proxy\'yi ayarlayın. Etkin genel proxy\'yi yalnızca ilk cihaz yöneticisi ayarlar."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Şifre süre sonu tarihi ayarla"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Deplm şifrelemesini ayarla"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Depolanan uygulama verisinin şifrelenmiş olmasını gerektir"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Ev"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"İş"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Diğer"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"PIN kodunu gir"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Şifre girmek için dokunun"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Kilidi açmak için şifreyi girin"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Kilidi açmak için PIN\'i girin"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Yanlış PIN kodu!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Şifre"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Oturum aç"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Geçersiz kullanıcı adı veya şifre."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Kullanıcı adınızı veya şifrenizi mi unuttunuz?"\n<b>"google.com/accounts/recovery"</b>" adresini ziyaret edin"</string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrol ediliyor..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Kilit Aç"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sesi aç"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"OtoDoldr"</string>
<string name="setup_autofill" msgid="8154593408885654044">"Oto Doldr Ayarla"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Tarayıcı geçmişini ve favorileri oku"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"Uygulamaya Tarayıcının ziyaret etmiş olduğu tüm URL\'leri ve Tarayıcının tüm favorilerini okuma izni verir."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"Tarayıcı geçmişini ve favorileri yaz"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
<string name="select_input_method" msgid="6865512749462072765">"Giriş yöntemini seç"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Giriş yöntemlerini yapılandır"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 eşleşme"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> / <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"Bitti"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB depolama biriminin bağlantısı kesiliyor..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD kartın bağlantısı kesiliyor..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB dep brm silinyr..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Paylaş"</string>
<string name="find" msgid="4808270900322985960">"Bul"</string>
<string name="websearch" msgid="4337157977400211589">"Google Web Arama"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> kullanıcısından gelen konum isteği"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Konum isteği"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> tarafından istendi (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Evet"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Hayır"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Silme sınırı aşıldı"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> hesabı için <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> silinmiş öğe var. Ne yapmak istiyorsunuz?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Öğeleri sil."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Silme işlemlerini geri alın."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Şimdilik bir şey yapma."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlandı"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlantısı kesildi"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"VPN\'ye tekrar bağlanmak için dokunun."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Bir hesap seçin"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Artır"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Azalt"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a2ad6dc..2a3624f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Режим польоту"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Режим польоту ВВІМК."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Режим польоту ВИМК."</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Служби, які потребують оплати"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Дозволяє власнику прив\'язувати до інтерфейсу верхнього рівня методу введення. Ніколи не потрібний для звичайних програм."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"прив\'зати до фон. мал."</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Дозволяє власнику прив\'язувати до інтерфейсу верхнього рівня фон. малюнка. Ніколи не потрібний для звичайних програм."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"прив\'язувати до служби віджетів"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Дозволяє власнику прив\'язувати до інтерфейсу верхнього рівня служби віджетів. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаємодіяти з адмін. пристрою"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Дозволяє власнику надсилати цілі адміністратору пристрою. Ніколи не потрібний для звичайних програм."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"змінювати орієнтацію екрана"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Дозволяє програмі контролювати світловий сигнал."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"отр.дост.до прист.USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Дозволяє програмі отрим. доступ до пристр. USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"впроваджувати протокол MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Дозволяє доступ до драйвера ядра MTP для впровадження протоколу MTP (USB)."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"тест-ти обладн."</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Дозволяє програмі контрол. різні периферійні пристрої для тестування апаратного забезпечення."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"прямо набирати номери тел."</string>
@@ -465,8 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"змінювати/видал. вміст карти SD"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Дозволяє програмі записувати на носій USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Дозволяє програмі записувати на карту SD."</string>
- <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змін./видаляти вміст внутр. сховища медіа-файлів"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Дозволяє програмі змінювати вміст внутрішнього сховища медіа-файлів."</string>
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змінювати/видаляти вміст внутр. сховища даних"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Дозволяє програмі змінювати вміст внутрішнього сховища даних."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"отр. дост. до файл. сист. кешу"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Дозволяє програмі зчитувати та записувати файлову сист. кешу."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"здійсн./отрим. Інтернет-дзвін."</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Устан. використ. глоб. проксі, коли ввімкнено політику. Лише адміністратор першого пристрою встановлює активний глоб. проксі."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Установити термін дії пароля"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Регулює, за скільки часу перед блокуванням екрана треба змінювати пароль"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Установити шифрування носія"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Потрібно, щоб дані збереженої програми були зашифровані"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Дом."</item>
<item msgid="869923650527136615">"Мобільний"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Робоча"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Інша"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Введіть PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Торк. для введ. паролю"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Введіть пароль, щоб розбл."</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Введ. PIN для розблок."</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Неправильний PIN-код!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Пароль"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Увійти"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Недійсне ім\'я корист. чи пароль."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Не пам\'ятаєте ім\'я користувача чи пароль?"\n"Відвідайте сторінку "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Перевірка..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Розблок."</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Увімк. звук"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB підключ."</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Вибер., щоб вимкн. налагодж. USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Виберіть метод введ-ня"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Налаштувати методи введення"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Надіслати"</string>
<string name="find" msgid="4808270900322985960">"Знайти"</string>
<string name="websearch" msgid="4337157977400211589">"Веб-пошук"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Запит про місцезнаходження від користувача <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Запит про місцезнаходження"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Запит зроблено користувачем <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Так"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Ні"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Перевищено ліміт видалень"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Для <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, облікового запису <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>, існує стільки видалених елементів: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Що робити?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Видалити елементи."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Скасувати видалення."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Наразі нічого не робіть."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Профіль <xliff:g id="PROFILENAME">%s</xliff:g> підключено через VPN"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> роз\'єднано"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Торкніться для повторного з\'єднання з VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Вибрати обліковий запис"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Додати"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Відняти"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4e5220a..3306125 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -151,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Chế độ trên máy bay"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Chế độ trên máy bay BẬT"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Chế độ trên máy bay TẮT"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
<string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Dịch vụ tính tiền của bạn"</string>
@@ -256,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Cho phép chủ nhân ràng buộc với giao diện cấp cao nhất của phương thức nhập. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"liên kết với hình nền"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Cho phép chủ nhân ràng buộc với giao diện cấp cao nhất của hình nền. Không cần thiết cho các ứng dụng thông thường."</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"liên kết với dịch vụ tiện ích con"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"Cho phép chủ nhân liên kết với giao diện cấp cao nhất của dịch vụ tiện ích con. Không cần thiết đối với ứng dụng thông thường."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"tương tác với quản trị viên thiết bị"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"Cho phép chủ nhân gửi các ý định đến quản trị viên thiết bị. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"thay đổi hướng màn hình"</string>
@@ -286,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể bởi nhà sản xuất hoặc nhà cung cấp dịch vụ."</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"bật hoặc vô hiệu hoá các thành phần ứng dụng"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"Cho phép ứng dụng thay đổi việc có nên bật thành phần của ứng dụng khác hay không. Các ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa các tính năng quan trọng của máy tính bảng. Phải cẩn thận khi sử dụng quyền này vì nó có thể khiến các thành phần rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
- <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Cho phép ứng dụng thay đổi việc có nên bật thành phần của ứng dụng khác hay không. Các ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa các tính năng quan trọng của điện thoại. Phải cẩn thận khi sử dụng các quyền vì nó có thể khiến các thành phần ứng dụng rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"Cho phép ứng dụng thay đổi việc có nên bật thành phần của ứng dụng khác hay không. Các ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa các tính năng quan trọng của điện thoại. Phải cẩn thận khi sử dụng quyền này vì quyền này có thể khiến các thành phần ứng dụng rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"đặt ứng dụng ưa thích"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"Cho phép ứng dụng sửa đổi các ứng dụng ưa thích của bạn. Quyền này có thể cho phép các ứng dụng độc hại ngầm thay đổi các ứng dụng đã được chạy, giả mạo các ứng dụng hiện có để thu thập dữ liệu cá nhân của bạn."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"sửa đổi cài đặt hệ thống chung"</string>
@@ -362,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"Cho phép ứng dụng kiểm soát đèn nháy."</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"truy cập bộ nhớ USB"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"Cho phép ứng dụng truy cập thiết bị USB."</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"triển khai giao thức MTP"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"Cho phép truy cập tới trình điều khiển MTP nhân hệ điều hành để triển khai giao thức MTP USB."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"kiểm tra phần cứng"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"Cho phép ứng dụng kiểm soát các thiết bị ngoại vi khác nhau nhằm mục đích kiểm tra phần cứng."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"gọi trực tiếp số điện thoại"</string>
@@ -466,7 +465,7 @@
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"C.phép ứ.dụng ghi vào b.nhớ USB."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Cho phép ứng dụng ghi vào thẻ SD."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Cho phép ứng dụng sửa đổi nội dung của bộ nhớ phương tiện nội bộ."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Cho phép ứng dụng sửa đổi nội dung của bộ nhớ phương tiện cục bộ."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"truy cập hệ thống tệp bộ nhớ cache"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Cho phép ứng dụng đọc và ghi hệ thống tệp bộ nhớ cache."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"thực hiện/nhận cuộc gọi qua Internet"</string>
@@ -487,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Đặt proxy chung của điện thoại được sử dụng trong khi chính sách được bật. Chỉ quản trị viên đầu tiên của điện thoại mới có thể đặt proxy chung hiệu quả."</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"Đặt hết hạn mật khẩu"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"Kiểm soát thời lượng trước khi mật khẩu khóa màn hình cần được thay đổi"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Đặt mã hóa dung lượng lưu trữ"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"Yêu cầu dữ liệu ứng dụng được lưu trữ phải được mã hóa"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Nhà riêng"</item>
<item msgid="869923650527136615">"ĐT di động"</item>
@@ -601,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Cơ quan"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Khác"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"Nhập mã PIN"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"Chạm để nhập mật khẩu"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"Nhập mật khẩu để mở khoá"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"Nhập PIN để mở khóa"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Mã PIN không chính xác!"</string>
@@ -644,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mật khẩu"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Đăng nhập"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Đang kiểm tra..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khoá"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bật âm thanh"</string>
@@ -900,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hoá gỡ lỗi USB."</string>
<string name="select_input_method" msgid="6865512749462072765">"Chọn phương thức nhập"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"Định cấu hình phương pháp nhập liệu"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string>
@@ -998,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"Chia sẻ"</string>
<string name="find" msgid="4808270900322985960">"Tìm"</string>
<string name="websearch" msgid="4337157977400211589">"Tìm kiếm trên web"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"Yêu cầu vị trí từ <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"Yêu cầu vị trí"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"Được yêu cầu bởi <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"Có"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"Không"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"Đã vượt quá giới hạn xóa"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Có <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> mục bị xóa cho <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, tài khoản <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Bạn muốn làm gì?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"Xóa mục."</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"Hoàn tác các tác vụ xóa."</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"Ngay bây giờ bạn không cần làm gì cả."</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"Đã kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"Đã ngắt kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"Chạm để kết nối lại với VPN."</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"Chọn tài khoản"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"Tăng dần"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"Giảm dần"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1cfc5cf..40ae40f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"正在关机..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板电脑会关闭。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"您的手机会关机。"</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"要关闭手机吗?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"没有最近的应用程序。"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"平板电脑选项"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"飞行模式"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"已开启飞行模式"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"已关闭飞行模式"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"需要您付费的服务"</string>
@@ -257,6 +255,8 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"允许手机用户绑定至输入法的顶级界面。普通应用程序从不需要使用此权限。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"绑定到壁纸"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"允许手机用户绑定到壁纸的顶级界面。应该从不需要将此权限授予普通应用程序。"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"绑定到窗口小部件服务"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"允许手机用户绑定到窗口小部件服务的顶级界面。普通应用程序一律无需此权限。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"与设备管理器交互"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"允许持有对象将意向发送到设备管理器。普通的应用程序一律无需此权限。"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"更改屏幕显示方向"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"允许应用程序读取/写入诊断组所拥有的任何资源(例如,/dev 中的文件)。这可能会影响系统稳定性和安全性。此权限仅供制造商或运营商诊断硬件问题。"</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"启用或停用应用程序组件"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"允许应用程序更改是否启用其他应用程序的组件。恶意应用程序可借此停用重要的平板电脑功能。使用此权限时请务必谨慎,因为这可能导致应用程序组件陷入不可用、不一致或不稳定的状态。"</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"允许应用程序更改是否启用其他应用程序的组件。恶意应用程序可借此停用重要的平板电脑功能。使用此权限时请务必谨慎,因为这可能导致应用程序组件陷入不可用、不一致或不稳定的状态。"</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"允许应用程序更改是否启用其他应用程序的组件。恶意应用程序可借此停用重要的手机功能。使用此权限时请务必谨慎,因为这可能导致应用程序组件陷入不可用、不一致或不稳定的状态。"</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"设置首选应用程序"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"允许应用程序修改首选的应用程序。这样恶意应用程序可能会暗中更改运行的应用程序,从而骗过您的现有应用程序来收集您的保密数据。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"修改全局系统设置"</string>
@@ -363,10 +363,8 @@
<string name="permdesc_flashlight" msgid="6433045942283802309">"允许应用程序控制闪光灯。"</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"访问 USB 设备"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"允许应用程序访问 USB 设备。"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"应用 MTP 协议"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"允许访问内核 MTP 驱动程序,以便应用 MTP USB 协议。"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"测试硬件"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"允许应用程序控制各外围设备以进行硬件测试。"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"直接拨打电话号码"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"修改/删除 SD 卡中的内容"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"允许应用程序写入 USB 存储设备。"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"允许应用程序写入 SD 卡。"</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/删除内部媒体存储设备的内容"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"允许应用程序修改内部媒体存储设备的内容。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"允许应用程序读取和写入缓存文件系统。"</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"拨打/接听互联网通话"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"请设置在启用政策的情况下要使用的设备全局代理。只有第一设备管理员才可设置有效的全局代理。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"设置密码有效期"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"控制屏幕锁定密码的使用期限"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"设置存储设备加密"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"需要对存储的应用程序数据进行加密"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住宅"</item>
<item msgid="869923650527136615">"手机"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"单位"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"输入 PIN 码"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"触摸可输入密码"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"输入密码进行解锁"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"输入 PIN 进行解锁"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 码不正确!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密码"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登录"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"用户名或密码无效。"</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"忘记了您的用户名或密码?"\n"请访问 "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"正在检查..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"解锁"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"打开声音"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"自动填充"</string>
<string name="setup_autofill" msgid="8154593408885654044">"设置自动填充"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"读取浏览器的历史记录和书签"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"允许应用程序读取用浏览器访问过的所有网址,以及浏览器的所有书签。"</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"写入浏览器的历史记录和书签"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"选择停用 USB 调试。"</string>
<string name="select_input_method" msgid="6865512749462072765">"选择输入法"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"配置输入法"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 个匹配项"</item>
<item quantity="other" msgid="4641872797067609177">"第 <xliff:g id="INDEX">%d</xliff:g> 项,共 <xliff:g id="TOTAL">%d</xliff:g> 项"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"完成"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"正在卸载 USB 存储设备..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"正在卸载 SD 卡..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"正在格式化 USB 存储设备"</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"分享"</string>
<string name="find" msgid="4808270900322985960">"查找"</string>
<string name="websearch" msgid="4337157977400211589">"网页搜索"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"来自<xliff:g id="NAME">%s</xliff:g>的定位请求"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"定位请求"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"请求人:<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"超出删除限制"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"帐户 <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 有 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 个关于<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>的删除项。您要如何操作?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"删除这些项。"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"撤消删除。"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"目前不进行任何操作。"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”已连接"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”已断开连接"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"触摸可重新连接到 VPN。"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"选择帐户"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"减少"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d0f460f..784d86f 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -138,8 +138,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"關機中..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"您的平板電腦將會關機。"</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"手機即將關機。"</string>
- <!-- no translation found for shutdown_confirm_question (6656441286856415014) -->
- <skip />
+ <string name="shutdown_confirm_question" msgid="6656441286856415014">"您要關機嗎?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
<string name="no_recent_tasks" msgid="279702952298056674">"最近沒有存取應用程式。"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"平板電腦選項"</string>
@@ -152,8 +151,7 @@
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"飛航模式"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"飛航模式為 [開啟]"</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"飛航模式為 [關閉]"</string>
- <!-- no translation found for status_bar_notification_info_overflow (5833510281787786290) -->
- <skip />
+ <string name="status_bar_notification_info_overflow" msgid="5833510281787786290">"100+"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"需要額外費用的服務。"</string>
@@ -225,7 +223,7 @@
<string name="permlab_stopAppSwitches" msgid="4138608610717425573">"防止切換應用程式"</string>
<string name="permdesc_stopAppSwitches" msgid="3857886086919033794">"防止使用者切換到其他應用程式。"</string>
<string name="permlab_runSetActivityWatcher" msgid="7811586187574696296">"監視控制所有應用程式啟動狀態。"</string>
- <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"允許應用程式監視和控制系統啟動活動的方式。惡意應用程式可藉此破壞整個系統。這個權限只有開發人員才需要,一般使用上不需使用這個權限。"</string>
+ <string name="permdesc_runSetActivityWatcher" msgid="2149363027173451218">"允許應用程式監視和控制系統啟動活動的方式。惡意程式可能因此癱瘓整個系統。這個權限只有開發人員才需要,一般使用上不需使用這個權限。"</string>
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"傳送程式已移除廣播"</string>
<string name="permdesc_broadcastPackageRemoved" msgid="3453286591439891260">"允許應用程式在其他應用程式被移除時發送通知。請注意:惡意程式可能利用此功能,關閉其他執行中的程式。"</string>
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"傳送已接收 SMS 廣播"</string>
@@ -237,9 +235,9 @@
<string name="permlab_setAlwaysFinish" msgid="5342837862439543783">"關閉所有背景程式"</string>
<string name="permdesc_setAlwaysFinish" msgid="8773936403987091620">"允許應用程式控制哪些活動在被移到背景執行時,儘速結束。一般應用程式不需要此功能。"</string>
<string name="permlab_batteryStats" msgid="7863923071360031652">"編輯電池狀態"</string>
- <string name="permdesc_batteryStats" msgid="5847319823772230560">"允許修改電池狀態。一般應用程式不會使用此功能。"</string>
+ <string name="permdesc_batteryStats" msgid="5847319823772230560">"允修改收集到的電池用量統計資料。一般應用程式不應使用這項功能。"</string>
<string name="permlab_backup" msgid="470013022865453920">"控制系統備份與還原"</string>
- <string name="permdesc_backup" msgid="4837493065154256525">"允許應用程式控制系統備份與還原機制 (不建議一般應用程式使用)。"</string>
+ <string name="permdesc_backup" msgid="4837493065154256525">"允許應用程式控制系統的備份與還原機制。一般應用程式不應使用這項功能。"</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"顯示未授權視窗"</string>
<string name="permdesc_internalSystemWindow" msgid="5895082268284998469">"允許內部系統使用介面建立視窗。一般應用程式不會使用此功能。"</string>
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"顯示系統警示"</string>
@@ -257,14 +255,16 @@
<string name="permdesc_bindInputMethod" msgid="3734838321027317228">"允許擁有人連結至輸入法的最頂層介面。一般應用程式不需使用此選項。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"連結至桌布"</string>
<string name="permdesc_bindWallpaper" msgid="5287754520361915347">"允許擁有人連結至桌布的最頂層介面,一般應用程式不需使用此選項。"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
+ <string name="permdesc_bindRemoteViews" msgid="2930855984822926963">"允許應用程式繫結至小工具服務的頂層介面,一般應用程式不需使用此選項。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
<string name="permdesc_bindDeviceAdmin" msgid="8714424333082216979">"允許應用程式將調用請求 (intent) 傳送至裝置管理員;一般應用程式不需使用此選項。"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"變更螢幕顯示方向"</string>
- <string name="permdesc_setOrientation" msgid="6335814461615851863">"允許應用程式隨時變更螢幕顯示方向。一般應用程式不需要此功能。"</string>
+ <string name="permdesc_setOrientation" msgid="6335814461615851863">"允許應用程式可隨時變更螢幕旋轉方向。一般應用不應使用這項功能。"</string>
<string name="permlab_signalPersistentProcesses" msgid="4255467255488653854">"傳送 Linux 訊號到應用程式"</string>
<string name="permdesc_signalPersistentProcesses" msgid="3565530463215015289">"允許應用程式要求將支援的訊號傳送到所有持續的程序。"</string>
<string name="permlab_persistentActivity" msgid="8659652042401085862">"設定應用程式持續執行"</string>
- <string name="permdesc_persistentActivity" msgid="5037199778265006008">"允許應用程式持續執行,避免系統將它應用到其他程式。"</string>
+ <string name="permdesc_persistentActivity" msgid="5037199778265006008">"允許應用程式部分持續執行,避免系統將它用於其他應用程式。"</string>
<string name="permlab_deletePackages" msgid="3343439331576348805">"刪除應用程式"</string>
<string name="permdesc_deletePackages" msgid="3634943677518723314">"允許應用程式刪除 Android 程式。請注意:惡意程式可能利用此功能刪除重要應用程式。"</string>
<string name="permlab_clearAppUserData" msgid="2192134353540277878">"刪除其他應用程式資料"</string>
@@ -287,7 +287,7 @@
<string name="permdesc_diagnostic" msgid="3121238373951637049">"允許應用程式讀寫 diag 群組的資源;例如:/dev 裡的檔案。這可能會影響系統穩定性與安全性。此功能僅供製造商或技術人員用於硬體規格偵測。"</string>
<string name="permlab_changeComponentState" msgid="79425198834329406">"啟用或停用應用程式元件"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="4647419365510068321">"允許應用程式啟用或停用其他應用程式的元件。惡意應用程式可藉此停用重要的平板電腦功能。由於這個權限可能會導致應用程式元件無法使用、造成不一致或不穩定的問題,因此請謹慎斟酌授權。"</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"允許應用程式啟用或停用其他應用程式的元件。惡意應用程式可藉此停用重要的平板電腦功能。由於這個權限可能會導致應用程式元件無法使用、造成不一致或不穩定的問題,因此請謹慎斟酌授權。"</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="3443473726140080761">"允許應用程式啟用或停用其他應用程式的元件。請注意,惡意應用程式可利用此功能,停用重要的手機功能。此外,這個權限可能會導致應用程式元件無法使用、不一致或不穩定,因此請斟酌使用。"</string>
<string name="permlab_setPreferredApplications" msgid="3393305202145172005">"設定喜好的應用程式"</string>
<string name="permdesc_setPreferredApplications" msgid="760008293501937546">"允許應用程式修改您偏好的應用程式。請注意:惡意程式可能藉以秘密竄改執行的程式,或偽造已存在的程式以收集私人資料。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"編輯全域系統設定"</string>
@@ -332,7 +332,7 @@
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"變更音訊設定"</string>
<string name="permdesc_modifyAudioSettings" msgid="5793461287365991922">"允許應用程式編輯全域音訊設定,例如音量與路由。"</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"錄製音訊"</string>
- <string name="permdesc_recordAudio" msgid="6493228261176552356">"允許應用程式存取音訊錄製路徑。"</string>
+ <string name="permdesc_recordAudio" msgid="6493228261176552356">"允許應用程式存取錄音檔路徑。"</string>
<string name="permlab_camera" msgid="3616391919559751192">"拍照和拍攝影片"</string>
<string name="permdesc_camera" msgid="6004878235852154239">"允許應用程式使用相機拍照和錄影,此功能可讓應用程式隨時透過相機收集圖片。"</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"永久停用平板電腦"</string>
@@ -347,39 +347,37 @@
<string name="permdesc_mount_unmount_filesystems" msgid="6253263792535859767">"允許應用程式掛載/卸載抽取式儲存設備的檔案系統。"</string>
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"將外接式儲存裝置格式化"</string>
<string name="permdesc_mount_format_filesystems" msgid="574060044906047386">"允許應用程式將可移除式儲存裝置格式化。"</string>
- <string name="permlab_asec_access" msgid="3411338632002193846">"取得內存空間的資訊"</string>
- <string name="permdesc_asec_access" msgid="8820326551687285439">"允許應用程式取得內存空間的資訊。"</string>
- <string name="permlab_asec_create" msgid="6414757234789336327">"建立內存空間"</string>
- <string name="permdesc_asec_create" msgid="2621346764995731250">"允許應用程式建立內存空間。"</string>
- <string name="permlab_asec_destroy" msgid="526928328301618022">"銷毀內存空間"</string>
- <string name="permdesc_asec_destroy" msgid="2746706889208066256">"允許應用程式銷毀內存空間。"</string>
- <string name="permlab_asec_mount_unmount" msgid="2456287623689029744">"掛接/卸載內存空間"</string>
- <string name="permdesc_asec_mount_unmount" msgid="5934375590189368200">"允許應用程式掛接/卸載內存空間。"</string>
- <string name="permlab_asec_rename" msgid="7496633954080472417">"重新命名內存空間"</string>
- <string name="permdesc_asec_rename" msgid="2152829985238876790">"允許應用程式重新命名內存空間。"</string>
+ <string name="permlab_asec_access" msgid="3411338632002193846">"取得內部儲存空間的資訊"</string>
+ <string name="permdesc_asec_access" msgid="8820326551687285439">"允許應用程式取得內部儲存空間的資訊。"</string>
+ <string name="permlab_asec_create" msgid="6414757234789336327">"建立內部儲存空間"</string>
+ <string name="permdesc_asec_create" msgid="2621346764995731250">"允許應用程式建立內部儲存空間。"</string>
+ <string name="permlab_asec_destroy" msgid="526928328301618022">"銷毀內部儲存空間"</string>
+ <string name="permdesc_asec_destroy" msgid="2746706889208066256">"允許應用程式銷毀內部儲存空間。"</string>
+ <string name="permlab_asec_mount_unmount" msgid="2456287623689029744">"掛接/卸載內部儲存空間"</string>
+ <string name="permdesc_asec_mount_unmount" msgid="5934375590189368200">"允許應用程式掛接/卸載內部儲存空間。"</string>
+ <string name="permlab_asec_rename" msgid="7496633954080472417">"重新命名內部儲存空間"</string>
+ <string name="permdesc_asec_rename" msgid="2152829985238876790">"允許應用程式重新命名內部儲存空間。"</string>
<string name="permlab_vibrate" msgid="7768356019980849603">"控制震動"</string>
<string name="permdesc_vibrate" msgid="2886677177257789187">"允許應用程式控制震動。"</string>
<string name="permlab_flashlight" msgid="2155920810121984215">"控制閃光燈"</string>
<string name="permdesc_flashlight" msgid="6433045942283802309">"允許應用程式控制閃光燈。"</string>
<string name="permlab_accessUsb" msgid="7362327818655760496">"存取 USB 裝置"</string>
<string name="permdesc_accessUsb" msgid="2414271762914049292">"允許應用程式存取 USB 裝置。"</string>
- <!-- no translation found for permlab_accessMtp (4953468676795917042) -->
- <skip />
- <!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
- <skip />
+ <string name="permlab_accessMtp" msgid="4953468676795917042">"執行 MTP 通訊協定"</string>
+ <string name="permdesc_accessMtp" msgid="6532961200486791570">"允許存取核心 MTP 驅動程式,以執行 MTP USB 通訊協定。"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"測試硬體"</string>
<string name="permdesc_hardware_test" msgid="3668894686500081699">"允許應用程式控制各種週邊設備,以供測試用。"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"直接撥打電話號碼"</string>
<string name="permdesc_callPhone" msgid="3369867353692722456">"允許應用程式自行撥打電話。請注意:惡意程式可能任意撥打電話,造成預期外的支出。但此選項並不允許應用程式撥打緊急電話號碼。"</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"直接撥打任何電話號碼"</string>
- <string name="permdesc_callPrivileged" msgid="244405067160028452">"允許應用程式自行撥打任何電話號碼,包括緊急電話號碼。請注意:惡意程式可能利用此功能濫用緊急服務,撥打不必要或違法的電話。"</string>
+ <string name="permdesc_callPrivileged" msgid="244405067160028452">"允許應用程式自行撥打任何電話號碼,包括緊急電話號碼。請注意:惡意應用程式可能會利用此權限,向緊急服務撥打騷擾甚至非法電話。"</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"直接啟動 CDMA 平板電腦設定程序"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"直接起始 CDMA 手機設定程序"</string>
<string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"允許應用程式啟動 CDMA 服務 (惡意應用程式可能會在非必要的情況下啟動 CDMA 服務)。"</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"控制位置更新通知"</string>
- <string name="permdesc_locationUpdates" msgid="2300018303720930256">"允許啟用/停用無線通訊位置更新通知。一般應用程式不會使用此功能。"</string>
+ <string name="permdesc_locationUpdates" msgid="2300018303720930256">"允許從廣播中啟用/停用位置資訊更新通知。一般應用程式不應使用這項功能。"</string>
<string name="permlab_checkinProperties" msgid="7855259461268734914">"存取登機選項"</string>
- <string name="permdesc_checkinProperties" msgid="7150307006141883832">"允許讀寫登機服務上傳的資料。一般應用程式不會使用此功能。"</string>
+ <string name="permdesc_checkinProperties" msgid="7150307006141883832">"允許讀取/寫入由登錄服務所更新的屬性存取權。一般應用程式不應使用這項功能。"</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"選擇小工具"</string>
<string name="permdesc_bindGadget" msgid="2098697834497452046">"允許應用程式告知系統哪個應用程式可以使用哪些小工具。開啟此權限後,應用程式會讓其他程式使用個人資料,但一般應用程式不適合使用此功能。"</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"修改手機狀態"</string>
@@ -466,10 +464,8 @@
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"修改/刪除 SD 卡的內容"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"允許應用程式寫入 USB 儲存裝置。"</string>
<string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"允許應用程式寫入 SD 卡。"</string>
- <!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
- <skip />
- <!-- no translation found for permdesc_mediaStorageWrite (8232008512478316233) -->
- <skip />
+ <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/刪除內部媒體儲存裝置內容"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"允許應用程式修改內部媒體儲存裝置內容。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"存取快取檔案系統"</string>
<string name="permdesc_cache_filesystem" msgid="1624734528435659906">"允許應用程式讀取及寫入快取檔案系統。"</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"撥打/接聽網路電話"</string>
@@ -490,6 +486,8 @@
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域 Proxy,只有第一個裝置管理員所設定的全域 Proxy 具有效力。"</string>
<string name="policylab_expirePassword" msgid="2314569545488269564">"設定密碼到期日"</string>
<string name="policydesc_expirePassword" msgid="7276906351852798814">"控制螢幕鎖定密碼的使用期限"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"設定儲存裝置加密"</string>
+ <string name="policydesc_encryptedStorage" msgid="2504984732631479399">"必須為儲存的應用程式資料加密"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住家電話"</item>
<item msgid="869923650527136615">"行動電話"</item>
@@ -604,6 +602,7 @@
<string name="sipAddressTypeWork" msgid="6920725730797099047">"公司"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
<string name="keyguard_password_enter_pin_code" msgid="3731488827218876115">"輸入 PIN 碼"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7906561917570259833"><font size="17">"輕觸即可輸入密碼"</font></string>
<string name="keyguard_password_enter_password_code" msgid="9138158344813213754">"輸入密碼即可解鎖"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="638347075625491514">"輸入 PIN 進行解鎖"</string>
<string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"PIN 碼錯誤!"</string>
@@ -647,6 +646,7 @@
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密碼"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登入"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"使用者名稱或密碼錯誤。"</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"忘了使用者名稱或密碼?"\n"請前往 "<b>"google.com/accounts/recovery"</b></string>
<string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"檢查中..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"解除封鎖"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"開啟音效"</string>
@@ -668,11 +668,9 @@
<string name="autofill_this_form" msgid="1272247532604569872">"自動填入功能"</string>
<string name="setup_autofill" msgid="8154593408885654044">"設定自動填入功能"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
- <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
- <skip />
+ <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
- <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
- <skip />
+ <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"讀取瀏覽器的記錄與書籤"</string>
<string name="permdesc_readHistoryBookmarks" msgid="4981489815467617191">"允許應用程式讀取瀏覽器曾經造訪過的所有網址,以及瀏覽器的所有書籤。"</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"寫入瀏覽器的記錄與書籤"</string>
@@ -905,6 +903,7 @@
<string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string>
<string name="adb_active_notification_message" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
<string name="select_input_method" msgid="6865512749462072765">"選取輸入方式"</string>
+ <string name="configure_input_methods" msgid="6324843080254191535">"設定輸入方式"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
@@ -986,8 +985,7 @@
<item quantity="one" msgid="8167147081136579439">"1 個相符項目"</item>
<item quantity="other" msgid="4641872797067609177">"第 <xliff:g id="INDEX">%d</xliff:g> 個相符項目 (共 <xliff:g id="TOTAL">%d</xliff:g> 個相符項目)"</item>
</plurals>
- <!-- no translation found for action_mode_done (7217581640461922289) -->
- <skip />
+ <string name="action_mode_done" msgid="7217581640461922289">"完成"</string>
<string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"正在卸載 USB 儲存裝置..."</string>
<string name="progress_unmounting" product="default" msgid="5556813978958789471">"正在卸載 SD 卡..."</string>
<string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"正在清除 USB 儲存裝置..."</string>
@@ -1004,24 +1002,20 @@
<string name="share" msgid="1778686618230011964">"分享"</string>
<string name="find" msgid="4808270900322985960">"尋找"</string>
<string name="websearch" msgid="4337157977400211589">"網頁搜尋"</string>
- <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
- <skip />
- <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
- <skip />
- <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
- <skip />
- <!-- no translation found for gpsVerifYes (2346566072867213563) -->
- <skip />
- <!-- no translation found for gpsVerifNo (1146564937346454865) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
- <skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
- <skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
- <skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
- <skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
- <skip />
+ <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> 的地點要求"</string>
+ <string name="gpsNotifTitle" msgid="5446858717157416839">"位置要求"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
+ <string name="sync_too_many_deletes" msgid="5296321850662746890">"已超過刪除上限"</string>
+ <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> 同步化 (<xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> 帳戶) 有 <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> 個刪除項目。您想如何處理?"</string>
+ <string name="sync_really_delete" msgid="8933566316059338692">"刪除這些項目。"</string>
+ <string name="sync_undo_deletes" msgid="8610996708225006328">"復原刪除。"</string>
+ <string name="sync_do_nothing" msgid="8717589462945226869">"暫不執行。"</string>
+ <string name="vpn_notification_title_connected" msgid="3197819122581348515">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已連線"</string>
+ <string name="vpn_notification_title_disconnected" msgid="4614192702448522822">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已中斷連線"</string>
+ <string name="vpn_notification_hint_disconnected" msgid="4689796928510104200">"輕觸即可重新連線至 VPN。"</string>
+ <string name="choose_account_label" msgid="4191313562041125787">"選取帳戶"</string>
+ <string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
+ <string name="number_picker_decrement_button" msgid="2576606679160067262">"減少"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index de53174..d9eccd6 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -778,6 +778,9 @@
<!-- Color of link text (URLs). -->
<attr name="textColorLink" format="reference|color" />
+ <!-- Reference to a drawable that will be drawn under the insertion cursor. -->
+ <attr name="textCursorDrawable" format="reference" />
+
<!-- Indicates that the content of a non-editable TextView can be selected.
Default value is false. EditText content is always selectable. -->
<attr name="textIsSelectable" format="boolean" />
@@ -2794,6 +2797,9 @@
<!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditSideNoPasteWindowLayout" />
+ <!-- Reference to a drawable that will be drawn under the insertion cursor. -->
+ <attr name="textCursorDrawable" />
+
<!-- Indicates that the content of a non-editable text can be selected. -->
<attr name="textIsSelectable" />
</declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index aaf071b..4542575 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1642,4 +1642,7 @@
<!-- Default icon for applications that don't specify an icon. -->
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
+ <!-- Theme attribute used to customize the text insertion cursor -->
+ <!-- Commented out for HC MR1 to prevent an API change -->
+ <!-- <public type="attr" name="textCursorDrawable" id="0x01010362" /> -->
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d09210e..361bb6c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1413,10 +1413,10 @@
to be used while policy is enabled. Only the first device admin
sets the effective global proxy.</string>
<!-- Title of policy access to enforce password expiration [CHAR LIMIT=30]-->
- <string name="policylab_expirePassword">Set password expiration</string>
+ <string name="policylab_expirePassword">Set lock-screen password expiration</string>
<!-- Description of policy access to enforce password expiration [CHAR LIMIT=110]-->
- <string name="policydesc_expirePassword">Control how long before lockscreen password needs to be
- changed</string>
+ <string name="policydesc_expirePassword">Control how frequently the lock-screen password must be
+ changed</string>
<!-- Title of policy access to require encrypted storage [CHAR LIMIT=30]-->
<string name="policylab_encryptedStorage">Set storage encryption</string>
<!-- Description of policy access to require encrypted storage [CHAR LIMIT=110]-->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5700641..72f1801 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -426,6 +426,7 @@
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
<item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
<item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
+ <item name="android:textCursorDrawable">?android:attr/textCursorDrawable</item>
</style>
<style name="Widget.TextView.ListSeparator">
@@ -588,7 +589,7 @@
</style>
<style name="Widget.ListView.White" parent="Widget.AbsListView">
- <item name="android:listSelector">@android:drawable/list_selector_background_light</item>
+ <item name="android:listSelector">@android:drawable/list_selector_background</item>
<item name="android:cacheColorHint">?android:attr/colorBackgroundCacheHint</item>
<item name="android:divider">@android:drawable/divider_horizontal_bright_opaque</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 6d5b482..82164e5 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -105,7 +105,7 @@
<item name="listChoiceIndicatorSingle">@android:drawable/btn_radio</item>
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
@@ -180,6 +180,7 @@
<item name="textEditNoPasteWindowLayout">@android:layout/text_edit_no_paste_window</item>
<item name="textEditSidePasteWindowLayout">@android:layout/text_edit_side_paste_window</item>
<item name="textEditSideNoPasteWindowLayout">@android:layout/text_edit_side_no_paste_window</item>
+ <item name="textCursorDrawable">@null</item>
<!-- Widget styles -->
<item name="absListViewStyle">@android:style/Widget.AbsListView</item>
@@ -357,7 +358,7 @@
<item name="textColorLinkInverse">@android:color/link_text_dark</item>
<item name="editTextColor">?android:attr/textColorPrimary</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background_light</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="quickContactBadgeOverlay">@android:drawable/quickcontact_badge_overlay_light</item>
@@ -906,6 +907,7 @@
<item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@android:style/Widget.Holo.TextSelectHandle</item>
+ <item name="textCursorDrawable">@android:drawable/text_cursor_holo_dark</item>
<!-- Widget styles -->
<item name="absListViewStyle">@android:style/Widget.Holo.AbsListView</item>
@@ -1181,6 +1183,7 @@
<item name="textSelectHandleRight">@android:drawable/text_select_handle_right</item>
<item name="textSelectHandle">@android:drawable/text_select_handle_middle</item>
<item name="textSelectHandleWindowStyle">@android:style/Widget.Holo.TextSelectHandle</item>
+ <item name="textCursorDrawable">@android:drawable/text_cursor_holo_light</item>
<!-- Widget styles -->
<item name="absListViewStyle">@android:style/Widget.Holo.Light.AbsListView</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index fb8b5ce..7756135 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -30,7 +30,9 @@
import android.util.Log;
import android.view.KeyEvent;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import android.widget.LinearLayout;
@@ -485,6 +487,44 @@
}
/**
+ * @param pingServerList a list of servers that can be used for ping test, can be null
+ * @return true if the ping test is successful, false otherwise.
+ */
+ public boolean pingTest(String[] pingServerList) {
+ boolean result = false;
+ String[] hostList = {"www.google.com", "www.yahoo.com",
+ "www.bing.com", "www.facebook.com", "www.ask.com"};
+ if (pingServerList != null) {
+ hostList = pingServerList;
+ }
+ try {
+ // assume the chance that all servers are down is very small
+ for (int i = 0; i < hostList.length; i++ ) {
+ String host = hostList[i];
+ log("Start ping test, ping " + host);
+ Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
+ int status = p.waitFor();
+ if (status == 0) {
+ // if any of the ping test is successful, return true
+ result = true;
+ break;
+ } else {
+ result = false;
+ log("ping " + host + " failed.");
+ }
+ }
+ } catch (UnknownHostException e) {
+ log("Ping test Fail: Unknown Host");
+ } catch (IOException e) {
+ log("Ping test Fail: IOException");
+ } catch (InterruptedException e) {
+ log("Ping test Fail: InterruptedException");
+ }
+ log("return");
+ return result;
+ }
+
+ /**
* Associate the device to given SSID
* If the device is already associated with a WiFi, disconnect and forget it,
* We don't verify whether the connection is successful or not, leave this to the test
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 4457de9..1374e7f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -107,6 +107,17 @@
} catch (Exception e) {
fail("thread in sleep is interrupted");
}
+ assertTrue("no uplink data connection after Wi-Fi tethering", mAct.pingTest(null));
+ // Wait for 5 minutes, and verify the data connection again.
+ // bug id: 3400027
+ try {
+ Thread.sleep(5 * 60 * 1000);
+ } catch (Exception e) {
+ fail("thread in sleep is interrupted");
+ }
+ // Verify the uplink data connection
+ assertTrue("no uplink data connection", mAct.pingTest(null));
+ // Disable soft AP
assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
// Wait for 30 seconds until Wi-Fi tethering is stopped
try {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index ae009ca6..2f2a283 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -243,6 +243,9 @@
ConnectivityManagerTestActivity.SHORT_TIMEOUT));
assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ // Run ping test to verify the data connection
+ assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
+
int i;
for (i = 0; i < mReconnectIterations; i++) {
// 1. Put device into sleep mode
@@ -271,6 +274,9 @@
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
assertEquals("Cellular connection is down", State.CONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
+
+ assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+
// Turn screen on again
mAct.turnScreenOn();
assertTrue("Wait for Wi-Fi enable timeout after wake up",
@@ -279,6 +285,7 @@
assertTrue("Wait for Wi-Fi connection timeout after wake up",
mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue("Reconnect to Wi-Fi network, but no data connection.", mAct.pingTest(null));
}
if (i == mReconnectIterations) {
writeOutput(String.format("iteration %d out of %d",
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 96b028a..672f252 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -250,8 +250,8 @@
for (int i = 0; i < iterations; i++) {
mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
- mTestUtils.connectInput(adapter, device);
- mTestUtils.disconnectInput(adapter, device);
+ mTestUtils.connectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
+ mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
}
mTestUtils.unpair(adapter, device);
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index effed76..35210e5 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -238,6 +238,9 @@
case BluetoothProfile.HEADSET:
mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mConnectionAction = BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED;
+ break;
default:
mConnectionAction = null;
}
@@ -270,47 +273,6 @@
}
}
- private class ConnectInputReceiver extends FlagReceiver {
- private static final int STATE_DISCONNECTED_FLAG = 1;
- private static final int STATE_CONNECTING_FLAG = 1 << 1;
- private static final int STATE_CONNECTED_FLAG = 1 << 2;
- private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
-
- private BluetoothDevice mDevice;
-
- public ConnectInputReceiver(BluetoothDevice device, int expectedFlags) {
- super(expectedFlags);
-
- mDevice = device;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
- return;
- }
-
- if (BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED.equals(intent.getAction())) {
- int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, -1);
- assertNotSame(-1, state);
- switch (state) {
- case BluetoothInputDevice.STATE_DISCONNECTED:
- setFiredFlag(STATE_DISCONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTING:
- setFiredFlag(STATE_CONNECTING_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTED:
- setFiredFlag(STATE_CONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- setFiredFlag(STATE_DISCONNECTING_FLAG);
- break;
- }
- }
- }
- }
-
private class ConnectPanReceiver extends FlagReceiver {
private static final int STATE_DISCONNECTED_FLAG = 1;
private static final int STATE_CONNECTING_FLAG = 1 << 1;
@@ -366,6 +328,9 @@
case BluetoothProfile.HEADSET:
mHeadset = (BluetoothHeadset) proxy;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = (BluetoothInputDevice) proxy;
+ break;
}
}
}
@@ -379,6 +344,9 @@
case BluetoothProfile.HEADSET:
mHeadset = null;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = null;
+ break;
}
}
}
@@ -393,6 +361,7 @@
private Context mContext;
private BluetoothA2dp mA2dp;
private BluetoothHeadset mHeadset;
+ private BluetoothInputDevice mInput;
/**
* Creates a utility instance for testing Bluetooth.
@@ -1078,142 +1047,6 @@
}
/**
- * Connects the local device with a remote HID device and checks to make sure that the profile
- * is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void connectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_CONNECTING_FLAG
- | ConnectInputReceiver.STATE_CONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("connectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("connectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_CONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- case BluetoothInputDevice.STATE_DISCONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.connectInputDevice(device));
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("connectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_CONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("connectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("connectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("connectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state, BluetoothInputDevice.STATE_CONNECTED,
- firedFlags, mask));
- }
-
- /**
- * Disconnects the local device with a remote HID device and checks to make sure that the
- * profile is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void disconnectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_DISCONNECTING_FLAG
- | ConnectInputReceiver.STATE_DISCONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("disconnectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("disconnectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- case BluetoothInputDevice.STATE_CONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.disconnectInputDevice(device));
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("disconnectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_DISCONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("disconnectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("disconnectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("disconnectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state,
- BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
- }
-
- /**
* Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
* the correct actions were broadcast.
*
@@ -1478,21 +1311,14 @@
int expectedFlags) {
String[] actions = {
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
- BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED};
+ BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
+ BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED};
ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
expectedFlags);
addReceiver(receiver, actions);
return receiver;
}
- private ConnectInputReceiver getConnectInputReceiver(BluetoothDevice device,
- int expectedFlags) {
- String[] actions = {BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED};
- ConnectInputReceiver receiver = new ConnectInputReceiver(device, expectedFlags);
- addReceiver(receiver, actions);
- return receiver;
- }
-
private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
int expectedFlags) {
String[] actions = {BluetoothPan.ACTION_PAN_STATE_CHANGED};
@@ -1511,15 +1337,20 @@
long s = System.currentTimeMillis();
switch (profile) {
case BluetoothProfile.A2DP:
- while (mA2dp != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mA2dp == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mA2dp;
case BluetoothProfile.HEADSET:
- while (mHeadset != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mHeadset == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mHeadset;
+ case BluetoothProfile.INPUT_DEVICE:
+ while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ sleep(POLL_TIME);
+ }
+ return mInput;
default:
return null;
}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
index 963c8ed..f6b1d04 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
@@ -22,7 +22,6 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
@@ -55,7 +54,6 @@
super.tearDown();
}
- @Suppress
@SmallTest
public void testQueryObjReassignment() {
mDatabase.enableWriteAheadLogging();
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
index 4516510..39258ae 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
@@ -74,7 +74,6 @@
mDatabase.setVersion(CURRENT_DATABASE_VERSION);
}
- @Suppress
@SmallTest
public void testEnableWriteAheadLogging() {
mDatabase.disableWriteAheadLogging();
@@ -87,7 +86,6 @@
assertEquals(pool, mDatabase.mConnectionPool);
}
- @Suppress
@SmallTest
public void testDisableWriteAheadLogging() {
mDatabase.execSQL("create table test (i int);");
@@ -104,7 +102,6 @@
assertFalse(db.isOpen());
}
- @Suppress
@SmallTest
public void testCursorsWithClosedDbConnAfterDisableWriteAheadLogging() {
mDatabase.disableWriteAheadLogging();
@@ -141,7 +138,6 @@
/**
* a transaction should be started before a standalone-update/insert/delete statement
*/
- @Suppress
@SmallTest
public void testStartXactBeforeUpdateSql() throws InterruptedException {
runTestForStartXactBeforeUpdateSql(INSERT);
@@ -753,7 +749,6 @@
*
* @throws InterruptedException
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay1() throws InterruptedException {
createTableAndClearCache();
@@ -812,7 +807,6 @@
* instead of mDatabase.beginTransactionNonExclusive(), use execSQL("BEGIN transaction")
* and instead of mDatabase.endTransaction(), use execSQL("END");
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay2() throws InterruptedException {
createTableAndClearCache();
@@ -869,7 +863,6 @@
* instead of committing the data, do rollback and make sure the data seen by the query
* within the transaction is now gone.
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay3() {
createTableAndClearCache();
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index 8cba52d..a66a884 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -17,3 +17,21 @@
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/common.mk
+
+# Validate all key maps.
+include $(CLEAR_VARS)
+
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+files := \
+ $(foreach file,$(keylayouts),frameworks/base/data/keyboards/$(file)) \
+ $(foreach file,$(keycharmaps),frameworks/base/data/keyboards/$(file)) \
+ $(foreach file,$(keyconfigs),frameworks/base/data/keyboards/$(file))
+
+LOCAL_MODULE := validate_framework_keymaps
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := validatekeymaps
+
+validate_framework_keymaps: $(files)
+ $(hide) $(validatekeymaps) $(files)
+
+include $(BUILD_PHONY_PACKAGE)
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 14d7c80..51a8b27 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -545,3 +545,129 @@
meta: fallback HOME
alt: fallback MENU
}
+
+### Gamepad buttons ###
+
+key BUTTON_A {
+ base: fallback BACK
+}
+
+key BUTTON_B {
+ base: fallback BACK
+}
+
+key BUTTON_C {
+ base: fallback BACK
+}
+
+key BUTTON_X {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Y {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Z {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_L1 {
+ base: none
+}
+
+key BUTTON_R1 {
+ base: none
+}
+
+key BUTTON_L2 {
+ base: none
+}
+
+key BUTTON_R2 {
+ base: none
+}
+
+key BUTTON_THUMBL {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_THUMBR {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+ base: fallback HOME
+}
+
+key BUTTON_SELECT {
+ base: fallback MENU
+}
+
+key BUTTON_MODE {
+ base: fallback MENU
+}
+
+key BUTTON_1 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_2 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_3 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_4 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_5 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_6 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_7 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_8 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_9 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_10 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_11 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_12 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_13 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_14 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_15 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_16 {
+ base: fallback DPAD_CENTER
+}
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 0aefc31..6d925d6 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -261,7 +261,6 @@
# key 239 "KEY_KBDILLUMUP"
# key 240 "KEY_UNKNOWN"
-
key 288 BUTTON_1
key 289 BUTTON_2
key 290 BUTTON_3
@@ -400,3 +399,16 @@
# key 502 KEY_BRL_DOT6
# key 503 KEY_BRL_DOT7
# key 504 KEY_BRL_DOT8
+
+
+# Joystick and game controller axes.
+# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x03 RX
+axis 0x04 RY
+axis 0x05 RZ
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
\ No newline at end of file
diff --git a/data/keyboards/Vendor_046d_Product_c216.kl b/data/keyboards/Vendor_046d_Product_c216.kl
new file mode 100644
index 0000000..6743323
--- /dev/null
+++ b/data/keyboards/Vendor_046d_Product_c216.kl
@@ -0,0 +1,37 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Logitech Dual Action Controller
+#
+
+key 0x120 BUTTON_A
+key 0x123 BUTTON_B
+key 0x121 BUTTON_X
+key 0x122 BUTTON_Y
+key 0x124 BUTTON_L1
+key 0x125 BUTTON_R1
+key 0x126 BUTTON_L2
+key 0x127 BUTTON_R2
+key 0x128 BUTTON_SELECT
+key 0x129 BUTTON_START
+key 0x12a BUTTON_THUMBL
+key 0x12b BUTTON_THUMBR
+
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x05 RZ
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl
new file mode 100644
index 0000000..f8ac6a3
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268.kl
@@ -0,0 +1,76 @@
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Sony Playstation(R)3 Controller
+#
+
+key 0x124 DPAD_UP
+key 0x125 DPAD_RIGHT
+key 0x126 DPAD_DOWN
+key 0x127 DPAD_LEFT
+
+key 0x120 BUTTON_SELECT
+key 0x123 BUTTON_START
+key 0x12f BUTTON_A
+key 0x12c BUTTON_B
+key 0x12e BUTTON_X
+key 0x12d BUTTON_Y
+key 0x12a BUTTON_L1
+key 0x12b BUTTON_R1
+key 0x128 BUTTON_L2
+key 0x129 BUTTON_R2
+key 0x121 BUTTON_THUMBL
+key 0x122 BUTTON_THUMBR
+
+# PS key
+key 0x2d0 BUTTON_1
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x02 Z
+axis 0x05 RZ
+
+# DPAD
+# axis 0x2c -HAT_Y
+# axis 0x2d +HAT_X
+# axis 0x2e +HAT_Y
+# axis 0x2f -HAT_X
+
+# L2 trigger
+axis 0x30 LTRIGGER
+
+# R2 trigger
+axis 0x31 RTRIGGER
+
+# L1 trigger
+# axis 0x32
+
+# R1 trigger
+# axis 0x33
+
+# Triangle
+# axis 0x34
+
+# Circle
+# axis 0x35
+
+# Cross
+# axis 0x36
+
+# Square
+# axis 0x37
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 56c287a..5b367b9 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -19,7 +19,9 @@
Generic.kl \
AVRCP.kl \
qwerty.kl \
+ Vendor_046d_Product_c216.kl \
Vendor_046d_Product_c532.kl \
+ Vendor_054c_Product_0268.kl \
Vendor_05ac_Product_0239.kl \
Vendor_22b8_Product_093d.kl
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index cbe3bf4..013cc94 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -83,6 +83,7 @@
<table>
<tr><th>Platform Version</th><th>API Level</th></tr>
+ <tr><td>Android 3.0</td><td>11</td></tr>
<tr><td>Android 2.3.3</td><td>10</td></tr>
<tr><td>Android 2.3</td><td>9</td></tr>
<tr><td>Android 2.2</td><td>8</td></tr>
diff --git a/docs/html/guide/developing/building/building-cmdline.jd b/docs/html/guide/developing/building/building-cmdline.jd
index a5ab07d..81c1178 100644
--- a/docs/html/guide/developing/building/building-cmdline.jd
+++ b/docs/html/guide/developing/building/building-cmdline.jd
@@ -1,4 +1,6 @@
page.title=Building and Running from the Command Line
+parent.title=Building and Running
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/building/building-eclipse.jd b/docs/html/guide/developing/building/building-eclipse.jd
index 85c82a9..6ebc49e 100644
--- a/docs/html/guide/developing/building/building-eclipse.jd
+++ b/docs/html/guide/developing/building/building-eclipse.jd
@@ -1,4 +1,6 @@
page.title=Building and Running from Eclipse with ADT
+parent.title=Building and Running
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/debugging/ddms.jd b/docs/html/guide/developing/debugging/ddms.jd
index 8f5e706..0d47ae5 100644
--- a/docs/html/guide/developing/debugging/ddms.jd
+++ b/docs/html/guide/developing/debugging/ddms.jd
@@ -1,4 +1,6 @@
page.title=Using DDMS
+parent.title=Debugging
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/debugging/debugging-devtools.jd b/docs/html/guide/developing/debugging/debugging-devtools.jd
index 67605ae..157d62e 100644
--- a/docs/html/guide/developing/debugging/debugging-devtools.jd
+++ b/docs/html/guide/developing/debugging/debugging-devtools.jd
@@ -1,4 +1,6 @@
page.title=Using the Dev Tools App
+parent.title=Debugging
+parent.link=index.html
@jd:body
<p>The Dev Tools application is installed by default on all system images included with the SDK,
diff --git a/docs/html/guide/developing/debugging/debugging-log.jd b/docs/html/guide/developing/debugging/debugging-log.jd
index ff73c17..295772d 100644
--- a/docs/html/guide/developing/debugging/debugging-log.jd
+++ b/docs/html/guide/developing/debugging/debugging-log.jd
@@ -1,4 +1,6 @@
page.title=Reading and Writing Logs
+parent.title=Debugging
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/debugging/debugging-projects-cmdline.jd b/docs/html/guide/developing/debugging/debugging-projects-cmdline.jd
index 6800a5d..3b5ceab 100644
--- a/docs/html/guide/developing/debugging/debugging-projects-cmdline.jd
+++ b/docs/html/guide/developing/debugging/debugging-projects-cmdline.jd
@@ -1,4 +1,6 @@
-page.title=Debugging from other IDEs
+page.title=Debugging from Other IDEs
+parent.title=Debugging
+parent.link=index.html
@jd:body
diff --git a/docs/html/guide/developing/debugging/debugging-projects.jd b/docs/html/guide/developing/debugging/debugging-projects.jd
index deb4341..2283f8b 100644
--- a/docs/html/guide/developing/debugging/debugging-projects.jd
+++ b/docs/html/guide/developing/debugging/debugging-projects.jd
@@ -1,4 +1,6 @@
page.title=Debugging from Eclipse with ADT
+parent.title=Debugging
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/debugging/debugging-tracing.jd b/docs/html/guide/developing/debugging/debugging-tracing.jd
index 0401966..72f6498 100644
--- a/docs/html/guide/developing/debugging/debugging-tracing.jd
+++ b/docs/html/guide/developing/debugging/debugging-tracing.jd
@@ -1,4 +1,6 @@
page.title=Profiling with Traceview and dmtracedump
+parent.title=Debugging
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/debugging/debugging-ui.jd b/docs/html/guide/developing/debugging/debugging-ui.jd
index 9b02d34..d2c42d5 100644
--- a/docs/html/guide/developing/debugging/debugging-ui.jd
+++ b/docs/html/guide/developing/debugging/debugging-ui.jd
@@ -1,4 +1,6 @@
page.title=Debugging and Profiling User Interfaces
+parent.title=Debugging
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
@@ -7,162 +9,498 @@
<ol>
<li>
- <a href="#hierarchyViewer">Debugging and Optimizing User Interfaces with Hierarchy
- Viewer</a>
- <ol>
- <li><a href="#layoutview">Layout View</a></li>
- <li><a href="#pixelperfect">Pixel Perfect View</a></li>
- </ol>
+ <a href="#HierarchyViewer">
+ Debugging and Optimizing User Interfaces with Hierarchy Viewer
+ </a>
+ <ol>
+ <li><a href="#runhv">Running Hierarchy Viewer and choosing a window</a></li>
+ <li><a href="#viewhierarchy">About the View Hierarchy window</a></li>
+ <li><a href="#indiView">Working with an individual View in Tree View</a></li>
+ <li><a href="#hvdebugging">Debugging with View Hierarchy</a></li>
+ <li><a href="#hvoptimize">Optimizing with View Hierarchy</a></li>
+ </ol>
</li>
-
+ <li>
+ <a href="#pixelperfect">
+ Examining and Designing User Interfaces with Pixel Perfect
+ </a>
+ <ol>
+ <li><a href="#aboutpixelperfect">About the Pixel Perfect window</a></li>
+ <li><a href="#overlays">Working with Pixel Perfect overlays</a></li>
+ </ol>
+ </li>
<li><a href="#layoutopt">Optimizing Layouts with <code>layoutopt</code></a></li>
</ol>
</div>
</div>
- <p>Sometimes your application's layout can slow down your application.
- To help debug issues in your layout, the Android SDK provides the Hierarchy Viewer and
+ <p>Sometimes your application's layout can slow down your application.
+ To help debug issues in your layout, the Android SDK provides the Hierarchy Viewer and
<code>layoutopt</code> tools.
</p>
-
+
<p>The Hierarchy Viewer application allows you to debug and optimize your user interface. It
- provides a visual representation of the layout's View hierarchy (the Layout View) and a magnified
- inspector of the display (the Pixel Perfect View).</p>
+ provides a visual representation of the layout's View hierarchy (the View Hierarchy window)
+ and a magnified view of the display (the Pixel Perfect window).</p>
<p><code>layoutopt</code> is a command-line tool that helps you optimize the layouts and layout
hierarchies of your applications. You can run it against your layout files or resource
directories to quickly check for inefficiencies or other types of problems that could be
affecting the performance of your application.</p>
- <h2 id="hierarchyViewer">Debugging and Optimizing User Interfaces with Hierarchy Viewer</h2>
+<h2 id="HierarchyViewer">Debugging and Optimizing User Interfaces with Hierarchy Viewer</h2>
- <p>To get the Hierarchy Viewer started:</p>
-
- <ol>
- <li>Connect your device or launch an emulator.</li>
-
- <li>From a terminal, launch <code>hierarchyviewer</code> from the <code><sdk>/tools/</code>
- directory.</li>
-
- <li>In the window that opens, you'll see a list of <strong>Devices</strong>. When a device is
- selected, a list of currently active <strong>Windows</strong> is displayed on the right. The
- <em><Focused Window></em> is the window currently in the foreground, and also the default
- window loaded if you do not select another.</li>
-
- <li>Select the window that you'd like to inspect and click <strong>Load View
- Hierarchy</strong>. The Layout View will be loaded. You can then load the Pixel Perfect View by
- clicking the second icon at the bottom-left of the window.</li>
- </ol>
-
- <p>If you've navigated to a different window on the device, press <strong>Refresh
- Windows</strong> to refresh the list of available windows on the right.</p>
-
-
- <h3 id="layoutview">Layout View</h3>
-
- <p>The Layout View offers a look at the View layout and properties. It has three views:</p>
-
- <ul>
- <li>Tree View: a hierarchy diagram of the Views, on the left.</li>
-
- <li>Properties View: a list of the selected View's properties, on the top-right.</li>
-
- <li>Wire-frame View: a wire-frame drawing of the layout, on the bottom-right.</li>
- </ul><br />
- <img src="{@docRoot}images/hierarchyviewer-layout.png"
+<h3 id="runhv">Running Hierarchy Viewer and choosing a window</h3>
+<p>
+ To run Hierarchy Viewer, follow these steps:</p>
+<ol>
+ <li>
+ Connect your device or launch an emulator.
+ <p>
+ To preserve security, Hierarchy Viewer can only connect to devices running a
+ developer version of the Android system.
+ </p>
+ </li>
+ <li>
+ If you have not done so already, install the application you want to work with.
+ </li>
+ <li>
+ Run the application, and ensure that its UI is visible.
+ </li>
+ <li>
+ From a terminal, launch <code>hierarchyviewer</code> from the
+ <code><sdk>/tools/</code>
+ directory.
+ </li>
+ <li>
+ The first window you see displays a list of devices and emulators. To expand the list
+ of Activity objects for a device or emulator, click the arrow on the left. This displays a
+ list of the Activity objects whose UI is currently visible on the device or emulator. The
+ objects are listed by their Android component name. The list includes both your application
+ Activity and system Activity objects. A screenshot of this window appears in
+ figure 1.
+ </li>
+ <li>
+ Select the name of your Activity from the list. You can now look at its view
+ hierarchy using the View Hierarchy window, or look at a magnified image of the UI using
+ the Pixel Perfect window.
+ </li>
+</ol>
+<p>
+ To learn how to use the View Hierarchy window, go to
+ <a href="#viewhierarchy">About the View Hierarchy window</a>. To learn how to use the
+ Pixel Perfect window, go to <a href="#pixelperfect">About the Pixel Perfect window</a>.
+</p>
+<img id="Fig1" src="{@docRoot}images/developing/hv_device_window.png" alt="" height="600"/>
+<p class="img-caption"><strong>Figure 1.</strong> Hierarchy Viewer device window</p>
+<h3 id="viewhierarchy">About the View Hierarchy window</h3>
+<p>
+ The View Hierarchy window displays the View objects that form the UI of the
+ Activity that is running on your device or emulator. You use it to look at individual
+ View objects within the context of the entire View tree. For each View object, the View
+ Hierarchy window also displays rendering performance data.
+</p>
+<p>
+ To see the View Hierarchy window, run Hierarchy Viewer as described in
+ the section <a href="#runhv">Running Hierarchy Viewer and choosing a window</a>. Next, click
+ <strong>View Hierarchy</strong> at the top of the device window.
+</p>
+<p>
+ You should see four panes:
+</p>
+<ul>
+ <li>
+ <strong>Tree View</strong>: The left-hand pane displays the Tree View,
+ a diagram of the Activity object's hierarchy of views. Use Tree View to examine individual
+ View objects and see the relationships between View objects in your UI.
+ <p>
+ To zoom in on the pane, use the slider at the bottom of the pane, or use your mouse
+ scroll wheel. To move around in the pane or reveal View objects that are not currently
+ visible, click and drag the pane.
+ </p>
+ <p>
+ To highlight the nodes in the tree whose class or ID match a search string, enter the
+ string in the <strong>Filter by class or id:</strong> edit box at the bottom of the
+ window. The background of nodes that match the search string will change from gray to
+ bright blue.
+ </p>
+ <p>
+ To save a screenshot of Tree View to a PNG file, click <strong>Save As PNG</strong> at
+ the top of the View Hierarchy window. This displays a dialog in which you can choose
+ a directory and file name.
+ </p>
+ <p>
+ To save a layered screenshot of your device or emulator to an Adobe Photoshop (PSD)
+ file, click <strong>Capture Layers</strong> at the top of the View Hierarchy window.
+ This displays a dialog in which you can choose a directory or file name.
+ Each View in the UI is saved as a separate Photoshop layer.
+ </p>
+ <p>
+ In Photoshop (or similar program that accepts .psd files), you can hide, show or edit a
+ layer independently of others. When you save a layered screenshot, you can examine and
+ modify the image of an individual View object. This helps you experiment with design
+ changes.
+ </p>
+ </li>
+ <li>
+ The upper right-hand pane displays the <strong>Tree Overview</strong>, a smaller map
+ representation of the entire Tree View window. Use Tree Overview to identify the part of the
+ view tree that is being displayed in Tree View.
+ <p>
+ You can also use Tree Overview to move around in the Tree View pane. Click and drag
+ the shaded rectangle over an area to reveal it in Tree View.
+ </p>
+ </li>
+ <li>
+ The middle right-hand pane displays the <strong>Properties View</strong>,
+ a list of the properties for a selected View object. With Properties View, you can
+ examine all the properties without having to look at your application source.
+ <p>
+ The properties are organized by category. To find an individual property, expand
+ a category name by clicking the arrow on its left. This reveals all the properties
+ in that category.
+ </p>
+ </li>
+ <li>
+ The lower right-hand pane displays the <strong>Layout View</strong>,
+ a block representation of the UI. Layout View is another way to navigate through your UI.
+ When you click on a View object in Tree View, its position in the UI is highlighted.
+ Conversely, when you click in an area of Layout View, the View object for that area is
+ highlighted in Tree View.
+ <p>
+ The outline colors of blocks in Layout View provide additional information:
+ </p>
+ <ul>
+ <li>
+ Bold red: The block represents the the View that is currently selected in
+ Tree View.
+ </li>
+ <li>
+ Light red: The block represents the parent of the block outlined in bold red.
+ </li>
+ <li>
+ White: The block represents a visible View that is not a parent or child of the
+ View that is currently selected in Tree View.
+ </li>
+ </ul>
+ </li>
+</ul>
+<p>
+ When the UI of the current Activity changes, the View Hierarchy window is not automatically
+ updated. To update it, click <strong>Load View Hierarchy</strong> at the top of the window.
+</p>
+<p>
+ Also, the window is not updated if you switch to a new Activity. To update it, start by
+ clicking the window selection icon in the bottom left-hand corner of the window. This
+ navigates back to the Window Selection window. From this window, click the Android
+ component name of the new Activity and then click <strong>Load View Hierarchy</strong>
+ at the top of the window.
+</p>
+<p>
+ A screenshot of the View Hierarchy window appears in figure 2.
+</p>
+<img id="Fig2" src="{@docRoot}images/developing/hv_view_hierarchy_window.png" alt="" height="600"/>
+<p class="img-caption"><strong>Figure 2.</strong> The View Hierarchy window</p>
+<h3 id="indiView">Working with an individual View in Tree View</h3>
+<p>
+ Each node in Tree View represents a single View. Some information is always visible. Starting
+ at the top of the node, you see the following:
+</p>
+<ol>
+ <li>
+ View class: The View object's class.
+ </li>
+ <li>
+ View object address: A pointer to View object.
+ </li>
+ <li>
+ View object ID: The value of the
+ <code><a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">android:id</a>
+ </code> attribute.
+ </li>
+ <li>
+ Performance indicators: A set of three colored dots that indicate the rendering
+ speed of this View relative to other View objects in the tree. The three dots
+ represent (from left to right) the measure, layout, and draw times of the rendering.
+ <p>
+ The colors indicate the following relative performance:
+ </p>
+ <ul>
+ <li>
+ Green: For this part of the render time, this View is in the faster 50% of all
+ the View objects in the tree. For example, a green dot for the measure time means
+ that this View has a faster measure time than 50% of the View objects in the tree.
+ </li>
+ <li>
+ Yellow: For this part of the render time, this View is in the slower 50% of all
+ the View objects in the tree. For example, a yellow dot for the layout time means
+ that this View has a slower layout time than 50% of the View objects in the tree.
+ </li>
+ <li>
+ Red: For this part of the render time, this View is the slowest one in the tree.
+ For example, a red dot for the draw time means that this View takes the most
+ time to draw of all the View objects in the tree.
+ </li>
+ </ul>
+ </li>
+ <li>
+ View index: The zero-based index of the View in its parent View. If it is the only child,
+ this is 0.
+ </li>
+</ol>
+<p>
+ When you select a node, additional information for the View appears in a small window above
+ the node. When you click one of the nodes, you see the following:
+</p>
+<ul>
+ <li>
+ Image: The actual image of the View, as it would appear in the emulator. If the View has
+ children, these are also displayed.
+ </li>
+ <li>
+ View count: The number of View objects represented by this node. This includes the View
+ itself and a count of its children. For example, this value is 4 for a View that has 3
+ children.
+ </li>
+ <li>
+ Render times: The actual measure, layout, and draw times for the View rendering, in
+ milliseconds. These represent the same values as the performance indicators mentioned in
+ the preceding section.
+ </li>
+</ul>
+<p>
+ An annotated screenshot of an individual node in the Tree View window appears in figure 3.
+</p>
+<img id="Fig3" src="{@docRoot}images/developing/hv_treeview_screenshot.png" alt="" height="600"/>
+<p class="img-caption"><strong>Figure 3.</strong> An annotated node in Tree View</p>
+<h3 id="hvdebugging">Debugging with View Hierarchy</h3>
+<p>
+ The View Hierarchy window helps you debug an application by providing a static display
+ of the UI. The display starts with your application's opening screen. As you step through
+ your application, the display remains unchanged until you redraw it by invalidating and
+ then requesting layout for a View.
+</p>
+<p>
+ To redraw a View in the display:
+</p>
+ <ul>
+ <li>
+ Select a View in Tree View. As you move up towards the root of the tree (to the
+ left in the Tree View), you see the highest-level View objects. Redrawing a high-level
+ object usually forces the lower-level objects to redraw as well.
+ </li>
+ <li>
+ Click <strong>Invalidate</strong> at the top of the window. This marks the View as
+ invalid, and schedules it for a redraw at the next point that a layout is requested.
+ </li>
+ <li>
+ Click <strong>Request Layout</strong> to request a layout. The View and its children
+ are redrawn, as well as any other View objects that need to be redrawn.
+ </li>
+ </ul>
+<p>
+ Manually redrawing a View allows you to watch the View object tree and examine the properties of
+ individual View objects one step at a time as you go through breakpoints in your code.
+</p>
+<h3 id="hvoptimize">Optimizing with View Hierarchy</h3>
+<p>
+ View Hierarchy also helps you identify slow render performance. You start by looking at the
+ View nodes with red or yellow performance indicators to identify the slower View objects. As you
+ step through your application, you can judge if a View is consistently slow or slow only in
+ certain circumstances.
+</p>
+<p>
+ Remember that slow performance is not necessarily evidence of a problem, especially for
+ ViewGroup objects. View objects that have more children and more complex View objects render
+ more slowly.
+</p>
+<p>
+ The View Hierarchy window also helps you find performance issues. Just by looking at the
+ performance indicators (the dots) for each View node, you can see which View objects are the
+ slowest to measure, layout, and draw. From that, you can quickly identify the problems you
+ should look at first.
+</p>
+<h2 id="pixelperfect">Examining and Designing User Interfaces with Pixel Perfect</h2>
+<p>
+ Pixel Perfect is a tool for examining pixel properties and laying out UIs from a design drawing.
+</p>
+<h3 id="aboutpixelperfect">About the Pixel Perfect window</h3>
+<p>
+ The Pixel Perfect window displays a magnified image of the screen that is currently
+ visible on the emulator or device. In it, you can examine the properties
+ of individual pixels in the screen image. You can also use the Pixel Perfect window
+ to help you lay out your application UI based on a bitmap design.
+</p>
+<p>
+ To see the Pixel Perfect window, run Hierarchy Viewer, as described in
+ the section <a href="#runhv">Running Hierarchy Viewer and choosing a window</a>. Next, click
+ <strong>Inspect Screenshot</strong> at the top of the device window. The Pixel Perfect window
+ appears.
+</p>
+<p>
+ In it, you see three panes:
+</p>
+<ul>
+ <li>
+ View Object pane: This is a hierarchical list of the View objects that are currently
+ visible on the device or emulator screen, including both the ones in your application and
+ the ones generated by the system. The objects are listed by their View class.
+ To see the class names of a View object's children, expand the View by clicking the
+ arrow to its left. When you click a View, its position is highlighted in the Pixel Perfect
+ pane on the right.
+ </li>
+ <li>
+ Pixel Perfect Loupe pane: This is the magnified screen image. It is overlaid by a grid in
+ which each square represents one pixel. To look at the information for a pixel, click in its
+ square. Its color and X,Y coordinates appear at the bottom of the pane.
+ <p>
+ The magenta crosshair in the pane corresponds to the positioning
+ crosshair in the next pane. It only moves when you move the crosshair in the next pane.
+ </p>
+ <p>
+ To zoom in or out on the image, use the <strong>Zoom</strong> slider at the bottom of
+ the pane, or use your mouse's scroll wheel.
+ </p>
+ <p>
+ When you select a pixel in the Loupe pane, you see the following information at the
+ bottom of the pane:
+ </p>
+ <ul>
+ <li>
+ Pixel swatch: A rectangle filled with the same color as the pixel.
+ </li>
+ <li>
+ HTML color code: The hexadecimal RGB code corresponding to the pixel color
+ </li>
+ <li>
+ RGB color values: A list of the (R), green (G), and blue (B) color values of the
+ pixel color. Each value is in the range 0-255.
+ </li>
+ <li>
+ X and Y coordinates: The pixel's coordinates, in device-specific pixel units.
+ The values are 0-based, with X=0 at the left of the screen and Y=0 at the top.
+ </li>
+ </ul>
+ </li>
+ <li>
+ Pixel Perfect pane: This displays the currently visible screen as it would appear in the
+ emulator.
+ <p>
+ You use the cyan crosshair to do coarse positioning. Drag the crosshair in the image,
+ and the Loupe crosshair will move accordingly. You can also click on a point in the
+ Pixel Perfect pane, and the crosshair will move to that point.
+ </p>
+ <p>
+ The image corresponding to the View object selected in the View Object pane is
+ outlined in a box that indicates the View object's position on the screen. For the
+ selected object, the box is bold red. Sibling and parent View objects have a light
+ red box. View objects that are neither parents nor siblings are in white.
+ </p>
+ <p>
+ The layout box may have other rectangles either inside or outside it, each of which
+ indicates part of the View. A purple or green rectangle indicates the View bounding box.
+ A white or black box inside the layout box represents the <strong>padding</strong>, the
+ defined distance between the View object's content and its bounding box. An outer white
+ or black rectangle represents the <strong>margins</strong>, the distance between the
+ View bounding box and adjacent View objects. The padding and margin boxes are white if
+ the layout background is black, and vice versa.
+ </p>
+ <p>
+ You can save the screen image being displayed in the Pixel Perfect pane as a PNG file.
+ This produces a screenshot of the current screen. To do this, click
+ <strong>Save as PNG</strong> at the top of the window. This displays a dialog,
+ in which you can choose a directory and filename for the file.
+ </p>
+ </li>
+</ul>
+<p>
+ The panes are not automatically refreshed when you change one of the View objects or go to
+ another Activity. To refresh the Pixel Perfect pane and the Loupe pane, click
+ <strong>Refresh Screenshot</strong> at the top of the window. This will change the panes
+ to reflect the current screen image. You still may need to refresh the View Object pane;
+ to do this, click <strong>Refresh Tree</strong> at the top of the window.
+</p>
+<p>
+ To automatically refresh the panes while you are debugging, set
+ <strong>Auto Refresh</strong> at the top of the window, and then set a refresh rate
+ with the <strong>Refresh Rate</strong> slider at the bottom of the Loupe pane.
+</p>
+<h3 id="overlays">Working with Pixel Perfect overlays</h3>
+<p>
+ You often construct a UI based on a design done as a bitmap image. The Pixel Perfect window
+ helps you match up your View layout to a bitmap image by allowing you to load the bitmap as an
+ <strong>overlay</strong> on the screen image.
+</p>
+<p>
+ To use a bitmap image as an overlay:
+</p>
+<ul>
+ <li>
+ Start your application in a device or emulator and navigate to the Activity whose UI you
+ want to work with.
+ </li>
+ <li>
+ Start Hierarchy Viewer and navigate to the Pixel Perfect window.
+ </li>
+ <li>
+ At the top of the window, click <strong>Load Overlay</strong>. A dialog opens, prompting
+ for the image file to load. Load the image file.
+ </li>
+ <li>
+ Pixel Perfect displays the overlay over the screen image in the Pixel Perfect pane. The
+ lower left corner of the bitmap image (X=0, Y=<em>max value</em>) is anchored on the lower
+ leftmost pixel (X=0, Y=<em>max screen</em>) of the screen.
+ <p>
+ By default, the overlay has a 50% transparency, which allows you to see the screen
+ image underneath. You can adjust this with the <strong>Overlay:</strong> slider at the
+ bottom of the Loupe pane.
+ </p>
+ <p>
+ Also by default, the overlay is not displayed in the Loupe pane. To display it,
+ set <strong>Show in Loupe</strong> at the top of the window.
+ </p>
+ </li>
+</ul>
+<p>
+ The overlay is not saved as part of the screenshot when you save the screen image as a PNG
+ file.
+</p>
+<p>
+ A screenshot of the Pixel Perfect window appears in figure 4.
+</p>
+<img id="Fig4" src="{@docRoot}images/developing/hv_pixelperfect.png"
alt=""
- height="509"
- width="700" />
- <p class="img-caption"><strong>Figure 1.</strong> Screenshot of Hierarchy Viewer</p>
+ height="600"/>
+<p class="img-caption"><strong>Figure 4.</strong> The Pixel Perfect window</p>
+<h2 id="layoutopt">Optimizing layouts with layoutopt</h2>
+<p>
+ The <code>layoutopt</code> tool lets you analyze the XML files that define your
+ application's UI to find inefficiencies in the view hierarchy.</p>
- <p>Select a node in the Tree View to display the properties of that element in the Properties
- View. When a node is selected, the Wire-frame View also indicates the bounds of the element with
- a red rectangle. Double click a node in the tree (or select it, and click <strong>Display
- View</strong>) to open a new window with a rendering of that element.</p>
-
- <p>The Layout View includes a couple other helpful features for debugging your layout:
- <strong>Invalidate</strong> and <strong>Request Layout</strong>. These buttons execute the
- respective View calls, {@link android.view.View#invalidate()} and {@link
- android.view.View#requestLayout()}, on the View element currently selected in the tree. Calling
- these methods on any View can be very useful when simultaneously running a debugger on your
- application.</p>
-
- <p>The Tree View can be resized by adjusting the zoom slider, below the diagram. The number of
- View elements in the window is also given here. You should look for ways to minimize the number
- of Views. The fewer View elements there are in a window, the faster it will perform.</p>
-
- <p>If you interact with the device and change the focused View, the diagram will not
- automatically refresh. You must reload the Layout View by clicking <strong>Load View
- Hierarchy</strong>.</p>
-
- <h3 id="pixelperfect">Pixel Perfect View</h3>
-
- <p>The Pixel Perfect View provides a magnified look at the current device window. It helps you
- design your UI better by giving you a closer look at your UI's image quality, alignment, and other
- aesthetic qualities. It has three views:</p>
-
- <ul>
- <li>Explorer View: shows the View hierarchy as a list, on the left.</li>
-
- <li>Normal View: a normal view of the device window, in the middle.</li>
-
- <li>Loupe View: a magnified, pixel-grid view of the device window, on the right.</li>
- </ul><br />
- <img src="{@docRoot}images/hierarchyviewer-pixelperfect.png"
- alt=""
- height="509"
- width="700" />
-
- <p>Click on an element in the Explorer View and a "layout box" will be drawn in the Normal View
- to indicate the layout position of that element. The layout box uses multiple rectangles, to
- indicate the normal bounds, the padding and the margin (as needed). The purple or green rectangle
- indicates the normal bounds of the element (the height and width). The inner white or black
- rectangle indicates the content bounds, when padding is present. A black or white rectangle
- outside the normal purple/green rectangle indicates any present margins. (There are two colors
- for each rectangle, in order to provide the best contrast based on the colors currently in the
- background.)</p>
-
- <p>A very handy feature for designing your UI is the ability to overlay an image in the Normal
- and Loupe Views. For example, you might have a mock-up image of how you'd like to layout your
- interface. By selecting <strong>Load...</strong> from the controls in the Normal View, you can
- choose the image from your computer and it will be placed atop the preview. Your chosen image
- will anchor at the bottom left corner of the screen. You can then adjust the opacity of the
- overlay and begin fine-tuning your layout to match the mock-up.</p>
-
- <p>The Normal View and Loupe View refresh at regular intervals (5 seconds by default), but the
- Explorer View does not. If you navigate away and focus on a different View, then you should
- refresh the Explorer's hierarchy by clicking <strong>Load View Hierarchy</strong>. This is even
- true when you're working in a window that holds multiple Views that are not always visible. If
- you do not, although the previews will refresh, clicking a View in the Explorer will not provide
- the proper layout box in the Normal View, because the hierarchy believes you are still focused on
- the prior View.</p>
-
- <p>Optional controls include:</p>
-
- <ul>
- <li><strong>Overlay</strong>: Load an overlay image onto the view and adjust its opacity.</li>
-
- <li><strong>Refresh Rate</strong>: Adjust how often the Normal and Loupe View refresh their
- display.</li>
-
- <li><strong>Zoom</strong>: Adjust the zoom level of the Loupe View.</li>
- </ul>
-
- <h2 id="layoutopt">Optimizing layouts with layoutopt</h2>
- <p>The <code>layoutopt</code> tool lets you analyze the XML files that represent your application's layout
- and finds ineffiencies in the view hierarchy.</p>
-
- <p>To run the tool, open a terminal and launch <code>layoutopt <resources></code> from your
- SDK <code>tools/</code> directory. In the command, supply a list of uncompiled resource xml files
- or directories that you want to analyze.</p>
-
- <p>When run, the tool loads the specified XML files and analyzes their layout structures and
- hierarchies according to a set of predefined rules. If it detects issues, it outputs information
- about the issues, giving filename, line numbers, description of issue, and for some types of
- issues a suggested resolution.</p>
-
- <p>Here's an example of the output:</p>
- <pre>
+<p>
+ To run the tool, open a terminal and launch <code>layoutopt <xmlfiles></code>
+ from your SDK <code>tools/</code> directory. The <xmlfiles> argument is a space-
+ delimited list of resources you want to analyze, either uncompiled resource xml files or
+ directories of such files.
+</p>
+<p>
+ The tool loads the specified XML files and analyzes their definitions and
+ hierarchies according to a set of predefined rules. For every issue it detects, it
+ displays the following information:
+</p>
+<ul>
+ <li>
+ The filename in which the issue was detected.
+ </li>
+ <li>
+ The line number for the issue.
+ </li>
+ <li>
+ A description of the issue, and for some types of issues it also suggests a resolution.
+ </li>
+</ul>
+<p>The following is a sample of the output from the tool:</p>
+<pre>
$ layoutopt samples/
samples/compound.xml
7:23 The root-level <FrameLayout/> can be replaced with <merge/>
@@ -188,15 +526,3 @@
7:19 The root-level <FrameLayout/> can be replaced with <merge/>
11:17 This LinearLayout layout or its FrameLayout parent is useless
</pre>
-
-<p>
-For more information on running the tool, see the
-<a href="${@docRoot}guide/developing/debugging/debugging-ui.html#layoutopt">layoutopt</a> reference.</p>
-
-
-
-
-
-
-
-
diff --git a/docs/html/guide/developing/devices/emulator.jd b/docs/html/guide/developing/devices/emulator.jd
index f61a437..fe00531 100644
--- a/docs/html/guide/developing/devices/emulator.jd
+++ b/docs/html/guide/developing/devices/emulator.jd
@@ -1,4 +1,6 @@
page.title=Using the Android Emulator
+parent.title=Managing Virtual Devices
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/devices/managing-avds-cmdline.jd b/docs/html/guide/developing/devices/managing-avds-cmdline.jd
index 02fd750..6feeeb6 100644
--- a/docs/html/guide/developing/devices/managing-avds-cmdline.jd
+++ b/docs/html/guide/developing/devices/managing-avds-cmdline.jd
@@ -1,4 +1,6 @@
page.title=Managing AVDs from the Command Line
+parent.title=Managing Virtual Devices
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/devices/managing-avds.jd b/docs/html/guide/developing/devices/managing-avds.jd
index 2913ac9..1817ce7 100644
--- a/docs/html/guide/developing/devices/managing-avds.jd
+++ b/docs/html/guide/developing/devices/managing-avds.jd
@@ -1,4 +1,6 @@
page.title=Managing AVDs with AVD Manager
+parent.title=Managing Virtual Devices
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/projects/projects-cmdline.jd b/docs/html/guide/developing/projects/projects-cmdline.jd
index b12864e..7c3e40e 100644
--- a/docs/html/guide/developing/projects/projects-cmdline.jd
+++ b/docs/html/guide/developing/projects/projects-cmdline.jd
@@ -1,4 +1,6 @@
page.title=Managing Projects from the Command Line
+parent.title=Managing Projects
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/projects/projects-eclipse.jd b/docs/html/guide/developing/projects/projects-eclipse.jd
index aa49663..40c17ed 100644
--- a/docs/html/guide/developing/projects/projects-eclipse.jd
+++ b/docs/html/guide/developing/projects/projects-eclipse.jd
@@ -1,4 +1,6 @@
page.title=Managing Projects from Eclipse with ADT
+parent.title=Managing Projects
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/testing/testing_eclipse.jd b/docs/html/guide/developing/testing/testing_eclipse.jd
index 2a5b771..4e9ecca 100644
--- a/docs/html/guide/developing/testing/testing_eclipse.jd
+++ b/docs/html/guide/developing/testing/testing_eclipse.jd
@@ -1,4 +1,6 @@
page.title=Testing from Eclipse with ADT
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
@@ -16,8 +18,8 @@
basic processes for creating and running applications with ADT, as described in
<a href="{@docRoot}guide/developing/projects/projects-eclipse.html">Managing Projects from
Eclipse</a>
- and <a href="guide/developing/building/building-eclipse.html">Building and Running from
-Eclipse</a>.
+ and <a href="{@docRoot}guide/developing/building/building-eclipse.html">Building and Running
+from Eclipse</a>.
You may also want to read
<a href="{@docRoot}guide/topics/testing/testing_android.html">Testing Fundamentals</a>,
which provides an overview of the Android testing framework.
diff --git a/docs/html/guide/developing/testing/testing_otheride.jd b/docs/html/guide/developing/testing/testing_otheride.jd
index 50cc4fa..93af979 100644
--- a/docs/html/guide/developing/testing/testing_otheride.jd
+++ b/docs/html/guide/developing/testing/testing_otheride.jd
@@ -1,4 +1,6 @@
page.title=Testing from Other IDEs
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/tools/MonkeyDevice.jd b/docs/html/guide/developing/tools/MonkeyDevice.jd
index 34bbba9..abcf8fd 100644
--- a/docs/html/guide/developing/tools/MonkeyDevice.jd
+++ b/docs/html/guide/developing/tools/MonkeyDevice.jd
@@ -1,4 +1,6 @@
page.title=MonkeyDevice
+parent.title=monkeyrunner
+parent.link=index.html
@jd:body
<style>
h4.jd-details-title {background-color: #DEE8F1;}
diff --git a/docs/html/guide/developing/tools/MonkeyImage.jd b/docs/html/guide/developing/tools/MonkeyImage.jd
index ae85cb5..2efc373 100644
--- a/docs/html/guide/developing/tools/MonkeyImage.jd
+++ b/docs/html/guide/developing/tools/MonkeyImage.jd
@@ -1,4 +1,6 @@
page.title=MonkeyImage
+parent.title=monkeyrunner
+parent.link=index.html
@jd:body
<style>
h4.jd-details-title {background-color: #DEE8F1;}
diff --git a/docs/html/guide/developing/tools/MonkeyRunner.jd b/docs/html/guide/developing/tools/MonkeyRunner.jd
index 871e06d..ea8d69e 100644
--- a/docs/html/guide/developing/tools/MonkeyRunner.jd
+++ b/docs/html/guide/developing/tools/MonkeyRunner.jd
@@ -1,5 +1,8 @@
page.title=MonkeyRunner
+parent.title=monkeyrunner
+parent.link=index.html
@jd:body
+
<style>
h4.jd-details-title {background-color: #DEE8F1;}
</style>
diff --git a/docs/html/guide/developing/tools/adb.jd b/docs/html/guide/developing/tools/adb.jd
index 26839a1..e891ccd 100644
--- a/docs/html/guide/developing/tools/adb.jd
+++ b/docs/html/guide/developing/tools/adb.jd
@@ -1,4 +1,6 @@
page.title=Android Debug Bridge
+parent.title=Tools
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index d3da285..731aef7 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -1,4 +1,4 @@
-page.title=Designing a Remote Interface Using AIDL
+page.title=Android Interface Definition Language (AIDL)
@jd:body
@@ -6,209 +6,367 @@
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#implementing">Implementing IPC Using AIDL</a>
+ <li><a href="#Defining">Defining an AIDL Interface</a>
<ol>
- <li><a href="#aidlsyntax">Create an .aidl File</a></li>
- <li><a href="#implementtheinterface">Implementing the Interface</a></li>
- <li><a href="#exposingtheinterface">Exposing Your Interface to Clients</a></li>
- <li><a href="#parcelable">Pass by value Parameters using Parcelables</a></li>
+ <li><a href="#Create">Create the .aidl file</a></li>
+ <li><a href="#Implement">Implement the interface</a></li>
+ <li><a href="#Expose">Expose the interface to clients</a></li>
</ol>
</li>
- <li><a href="#calling">Calling an IPC Method</a></li>
+ <li><a href="#PassingObjects">Passing Objects over IPC</a></li>
+ <li><a href="#Calling">Calling an IPC Method</a></li>
</ol>
-</div>
-</div>
-
-<p>Since each application runs in its own process, and you can write a service that
-runs in a different process from your Application's UI, sometimes you need to pass objects
-between processes. On the Android platform, one process can not normally access the memory
-of another process. So to talk, they need to decompose their objects into primitives that
-the operating system can understand, and "marshall" the object across that boundary for you.</p>
-
-<p>The code to do that marshalling is tedious to write, so we provide the AIDL tool to do it
-for you.</p>
-
-<p>AIDL (Android Interface Definition Language) is an <a
-href="http://en.wikipedia.org/wiki/Interface_description_language">IDL</a>
-language used to generate code that enables two processes on an Android-powered device
-to talk using interprocess communication (IPC). If you have code
-in one process (for example, in an Activity) that needs to call methods on an
-object in another process (for example, a Service), you would use AIDL to
-generate code to marshall the parameters.</p>
-<p>The AIDL IPC mechanism
- is interface-based, similar to COM or Corba, but lighter weight. It uses a proxy
- class to pass values between the client and the implementation. </p>
-
-
-<h2 id="implementing">Implementing IPC Using AIDL</h2>
-<p>Follow these steps to implement an IPC service using AIDL.</p>
+<h2>See also</h2>
<ol>
- <li><strong><a href="#aidlsyntax">Create your .aidl file</a> </strong>- This
- file defines an interface (<em>YourInterface</em>.aidl) that defines the
- methods and fields available to a client. </li>
- <li><strong>Add the .aidl file to your makefile</strong> - (the ADT Plugin for Eclipse
- manages this for you). Android includes the compiler, called
- AIDL, in the <code>tools/</code> directory. </li>
- <li><strong><a href="#implementtheinterface">Implement your interface methods</a></strong> -
- The AIDL compiler creates an interface in the Java programming language from your AIDL interface.
- This interface has an inner abstract class named Stub that inherits the
- interface (and implements a few additional methods necessary for the IPC
- call). You must create a class that extends <em>YourInterface</em>.Stub
- and implements the methods you declared in your .aidl file. </li>
- <li><strong><a href="#exposingtheinterface">Expose your interface to clients</a></strong> -
- If you're writing a service, you should extend {@link
- android.app.Service Service} and override {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of your class that implements your
- interface. </li>
+ <li><a href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a></li>
</ol>
-<h3 id="aidlsyntax">Create an .aidl File</h3>
-<p>AIDL is a simple syntax that lets you declare an interface with one or more
- methods, that can take parameters and return values. These parameters and return
- values can be of any type, even other AIDL-generated interfaces. <em>However, it
- is important to note</em> that you <em>must</em> import all non-built-in types,
- <em>even if they are defined in the same package as your interface</em>.
- Here are the data types that AIDL can support: </p>
+</div>
+</div>
+
+
+<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
+worked with. It allows you to define the programming interface that both
+the client and service agree upon in order to communicate with each other using
+interprocess communication (IPC). On Android, one process cannot normally access the
+memory of another process. So to talk, they need to decompose their objects into primitives that the
+operating system can understand, and marshall the objects across that boundary for you. The code to
+do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
+
+<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
+different applications to access your service for IPC and want to handle multithreading in your
+service. If you do not need to perform concurrent IPC across
+different applications, you should create your interface by <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a> or, if you want to perform IPC, but do <em>not</em> need to handle multithreading,
+implement your interface <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Messenger">using a Messenger</a>.
+Regardless, be sure that you understand <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a> before
+implementing an AIDL.</p>
+
+<p>Before you begin designing your AIDL interface, be aware that calls to an AIDL interface are
+direct function calls. You should not make assumptions about the thread in which the call
+occurs. What happens is different depending on whether the call is from a thread in the
+local process or a remote process. Specifically:</p>
+
<ul>
- <li>Primitive Java programming language types (int, boolean, etc)
- — No <code>import</code> statement is needed. </li>
- <li>One of the following classes (no <code>import</code> statements needed):
- <ul>
- <li><strong>String</strong></li>
- <li><strong>List</strong> - All elements in the List must be one of the types
- in this list, including other AIDL-generated interfaces and
- parcelables. List may optionally be used as a "generic" class (e.g.
- List<String>).
- The actual concrete class that the other side will receive
- will always be an ArrayList, although the method will be generated
- to use the List interface. </li>
- <li><strong>Map</strong> - All elements in the Map must be of one of the
- types in this list, including other AIDL-generated interfaces and
- parcelables. Generic maps, (e.g. of the form Map<String,Integer>
- are not supported.
- The actual concrete class that the other side will receive
- will always be a HashMap, although the method will be generated
- to use the Map interface.</li>
- <li><strong>CharSequence</strong> - This is useful for the CharSequence
- types used by {@link android.widget.TextView TextView} and other
- widget objects. </li>
- </ul>
- </li>
- <li>Other AIDL-generated interfaces, which are always passed by reference.
- An <code>import</code> statement is always needed for these.</li>
- <li>Custom classes that implement the <a href="#parcelable">Parcelable
- protocol</a> and are passed by value.
- An <code>import</code> statement is always needed for these.</li>
+<li>Calls made from the local process are executed in the same thread that is making the call. If
+this is your main UI thread, that thread continues to execute in the AIDL interface. If it is
+another thread, that is the one that executes your code in the service. Thus, if only local
+threads are accessing the service, you can completely control which threads are executing in it (but
+if that is the case, then you shouldn't be using AIDL at all, but should instead create the
+interface by <a href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a>).</li>
+
+<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
+your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
+happening at the same time. In other words, an implementation of an AIDL interface must be
+completely thread-safe.</li>
+
+<li>The {@code oneway} keyword modifies the behavior of remote calls. When used, a remote call does
+not block; it simply sends the transaction data and immediately returns.
+The implementation of the interface eventually receives this as a regular call from the {@link
+android.os.Binder} thread pool as a normal remote call. If {@code oneway} is used with a local call,
+there is no impact and the call is still synchronous.</li>
</ul>
-<p>Here is the basic AIDL syntax:</p>
-<pre>// My AIDL file, named <em>SomeClass</em>.aidl
-// Note that standard comment syntax is respected.
-// Comments before the import or package statements are not bubbled up
-// to the generated interface, but comments above interface/method/field
-// declarations are added to the generated interface.
-// Include your fully-qualified package statement.
-package com.android.sample;
-// See the list above for which classes need
-// import statements (hint--most of them)
-import com.android.sample.IAtmService;
+<h2 id="Defining">Defining an AIDL Interface</h2>
-// Declare the interface.
-interface IBankAccountService {
-
- // Methods can take 0 or more parameters, and
- // return a value or void.
- int getAccountBalance();
- void setOwnerNames(in List<String> names);
-
- // Methods can even take other AIDL-defined parameters.
- BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
+<p>You must define your AIDL interface in an {@code .aidl} file using the Java
+programming language syntax, then save it in the source code (in the {@code src/} directory) of both
+the application hosting the service and any other application that binds to the service.</p>
- // All non-Java primitive parameters (e.g., int, bool, etc) require
- // a directional tag indicating which way the data will go. Available
- // values are in, out, inout. (Primitives are in by default, and cannot be otherwise).
- // Limit the direction to what is truly needed, because marshalling parameters
- // is expensive.
- int getCustomerList(in String branch, out String[] customerList);
-}</pre>
+<p>When you build each application that contains the {@code .aidl} file, the Android SDK tools
+generate an {@link android.os.IBinder} interface based on the {@code .aidl} file and save it in
+the project's {@code gen/} directory. The service must implement the {@link android.os.IBinder}
+interface as appropriate. The client applications can then bind to the service and call methods from
+the {@link android.os.IBinder} to perform IPC.</p>
-<h3 id="implementtheinterface">Implementing the Interface</h3>
-<p>AIDL generates an interface file for you with the same name as your .aidl
- file. If you are using the Eclipse plugin, AIDL will automatically be run as part of
- the build process (you don't need to run AIDL first and then build your project).
- If you are not using the plugin, you should run AIDL first. </p>
-<p>The generated interface
- includes an abstract inner class named Stub that declares all the methods
- that you declared in your .aidl file. Stub also defines a few helper methods,
- most notably asInterface(), which takes an IBinder (passed to a client's onServiceConnected()
- implementation when applicationContext.bindService() succeeds), and returns an
- instance of the interface used to call the IPC methods. See the section
- <a href="#calling">Calling an IPC Method</a> for more details on how to make this cast.</p>
-<p>To implement your interface, extend <em>YourInterface</em>.Stub,
- and implement the methods. (You can create the .aidl file and implement the stub
- methods without building between--the Android build process will process .aidl
-files before .java files.) </p>
-<p>Here is an example of implementing an interface called IRemoteService, which exposes
- a single method, getPid(), using an anonymous instance:</p>
-<pre>// No need to import IRemoteService if it's in the same project.
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){
+<p>To create a bounded service using AIDL, follow these steps:</p>
+<ol>
+ <li><a href="#CreateAidl">Create the .aidl file</a>
+ <p>This file defines the programming interface with method signatures.</p>
+ </li>
+ <li><a href="#ImplementTheInterface">Implement the interface</a>
+ <p>The Android SDK tools generate an interface in the Java programming language, based on your
+{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
+{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
+{@code Stub} class and implement the methods.</p>
+ </li>
+ <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
+ <p>Implement a {@link android.app.Service Service} and override {@link
+android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
+class.</p>
+ </li>
+</ol>
+
+<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
+your first release must remain backward compatible in order to avoid breaking other applications
+that use your service. That is, because your {@code .aidl} file must be copied to other applications
+in order for them to access your service's interface, you must maintain support for the original
+interface.</p>
+
+
+<h3 id="Create">1. Create the .aidl file</h3>
+
+<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
+take parameters and return values. The parameters and return values can be of any type, even other
+AIDL-generated interfaces.</p>
+
+<p>You must construct the {@code .aidl} file using the Java programming language. Each {@code .aidl}
+file must define a single interface and requires only the interface declaration and method
+signatures.</p>
+
+<p>By default, AIDL supports the following data types:</p>
+
+<ul>
+ <li>All primitive types in the Java programming language (such as {@code int}, {@code long},
+{@code char}, {@code boolean}, and so on)</li>
+ <li>{@link java.lang.String}</li>
+ <li>{@link java.lang.CharSequence}</li>
+ <li>{@link java.util.List}
+ <p>All elements in the {@link java.util.List} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
+java.util.List} may optionally be used as a "generic" class (for example,
+<code>List<String></code>).
+The actual concrete class that the other side receives is always an {@link
+java.util.ArrayList}, although the method is generated to use the {@link
+java.util.List} interface.</p>
+ </li>
+ <li>{@link java.util.Map}
+ <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
+(such as those of the form
+{@code Map<String,Integer>} are not supported. The actual concrete class that the other side
+receives is always a {@link java.util.HashMap}, although the method is generated to
+use the {@link java.util.Map} interface.</p>
+ </li>
+</ul>
+
+<p>You must include an {@code import} statement for each additional type not listed above, even if
+they are defined in the same package as your interface.</p>
+
+<p>When defining your service interface, be aware that:</p>
+<ul>
+ <li>Methods can take zero or more parameters, and return a value or void.</li>
+ <li>All non-primitive parameters require a directional tag indicating which way the data goes.
+Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
+ <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
+ <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
+needed, because marshalling parameters is expensive.</p></li>
+ <li>All code comments included in the {@code .aidl} file are included in the generated {@link
+android.os.IBinder} interface (except for comments before the import and package
+statements).</li>
+ <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
+</ul>
+
+<p>Here is an example {@code .aidl} file:</p>
+
+<pre>
+// IRemoteService.aidl
+package com.example.android;
+
+// Declare any non-default types here with import statements
+
+/** Example service interface */
+interface IRemoteService {
+ /** Request the process ID of this service, to do evil things with it. */
+ int getPid();
+
+ /** Demonstrates some basic types that you can use as parameters
+ * and return values in AIDL.
+ */
+ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+ double aDouble, String aString);
+}
+</pre>
+
+<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
+build your application, the SDK tools generate the {@link android.os.IBinder} interface file in your
+project's {@code gen/} directory. The generated file name matches the {@code .aidl} file name, but
+with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
+IRemoteService.java}).</p>
+
+<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
+do not use Eclipse, then the Ant tool generates the binder class next time you build your
+application—you should build your project with <code>ant debug</code> (or <code>ant
+release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
+link against the generated class.</p>
+
+
+<h3 id="Implement">2. Implement the interface</h3>
+
+<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
+named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
+that is an abstract implementation of its parent interface (for example, {@code
+YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
+
+<p class="note"><strong>Note:</strong> {@code Stub} also
+defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
+android.os.IBinder} (usually the one passed to a client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
+returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
+Method</a> for more details on how to make this cast.</p>
+
+<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
+android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
+inherited from the {@code .aidl} file.</p>
+
+<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
+{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
+
+<pre>
+private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
public int getPid(){
return Process.myPid();
}
-}</pre>
-<p>A few rules about implementing your interface: </p>
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+};
+</pre>
+
+<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
+which defines the RPC interface for the service. In the next step, this instance is exposed to
+clients so they can interact with the service.</p>
+
+<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
<ul>
- <li>No exceptions that you throw will be sent back to the caller.</li>
- <li>By default, IPC calls are synchronous. If you know that an IPC service takes more than
- a few milliseconds to complete, you should not call it in the Activity/View thread,
- because it might hang the application (Android might display an "Application
- is Not Responding" dialog).
- Try to call them in a separate thread. </li>
- <li>Only methods are supported; you cannot declare static fields in an AIDL interface.</li>
+ <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
+about multithreading from the start and properly build your service to be thread-safe.</li>
+ <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
+milliseconds to complete a request, you should not call it from the activity's main thread, because
+it might hang the application (Android might display an "Application is Not Responding"
+dialog)—you should usually call them from a separate thread in the client. </li>
+ <li>No exceptions that you throw are sent back to the caller.</li>
</ul>
-<h3 id="exposingtheinterface">Exposing Your Interface to Clients</h3>
-<p>Now that you've got your interface implementation, you need to expose it to clients.
- This is known as "publishing your service." To publish a service,
- inherit {@link android.app.Service Service} and implement {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of the class that implements your interface.
- Here's a code snippet of a service that exposes the IRemoteService
- interface to clients. </p>
-<pre>public class RemoteService extends Service {
-...
-{@include development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
- exposing_a_service}
-}</pre>
+
+<h3 id="Expose">3. Expose the interface to clients</h3>
+
+<p>Once you've implemented the interface for your service, you need to expose it to
+clients so they can bind to it. To expose the interface
+for your service, extend {@link android.app.Service Service} and implement {@link
+android.app.Service#onBind onBind()} to return an instance of your class that implements
+the generated {@code Stub} (as discussed in the previous section). Here's an example
+service that exposes the {@code IRemoteService} example interface to clients. </p>
+
+<pre>
+public class RemoteService extends Service {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ // Return the interface
+ return mBinder;
+ }
+
+ private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+ public int getPid(){
+ return Process.myPid();
+ }
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+ };
+}
+</pre>
+
+<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
+bindService()} to connect to this service, the client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
+{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
+method.</p>
+
+<p>The client must also have access to the interface class, so if the client and service are in
+separate applications, then the client's application must have a copy of the {@code .aidl} file
+in its {@code src/} directory (which generates the {@code android.os.Binder}
+interface—providing the client access to the AIDL methods).</p>
+
+<p>When the client receives the {@link android.os.IBinder} in the {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
+<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
+parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
+
+<pre>
+IRemoteService mIRemoteService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Following the example above for an AIDL interface,
+ // this gets an instance of the IRemoteInterface, which we can use to call on the service
+ mIRemoteService = IRemoteService.Stub.asInterface(service);
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "Service has unexpectedly disconnected");
+ mIRemoteService = null;
+ }
+};
+</pre>
+
+<p>For more sample code, see the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> class in <a
+href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
-<h3 id="parcelable">Pass by value Parameters using Parcelables</h3>
+
+
+
+
+
+
+<h2 id="PassingObjects">Passing Objects over IPC</h2>
<p>If you have a class that you would like to send from one process to another through
-an AIDL interface, you can do that. You must ensure that the code for your class is available
-to the other side of the IPC. Generally, that means that you're talking to a service that you
-started.</p>
-<p>There are five parts to making a class support the Parcelable protocol:</b>
+an IPC interface, you can do that. However, you must ensure that the code for your class is
+available to the other side of the IPC channel and your class must support the {@link
+android.os.Parcelable} interface. Supporting the {@link android.os.Parcelable} interface is
+important because it allows the Android system to decompose objects into primitives that can be
+marshalled across processes.</p>
+
+<p>To create a class that supports the {@link android.os.Parcelable} protocol, you must do the
+following:</b>
<ol>
<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement the method <code>public void writeToParcel(Parcel out)</code> that takes the
-current state of the object and writes it to a parcel.</li>
-value in a parcel into your object.</li>
+<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
+current state of the object and writes it to a {@link android.os.Parcel}.</li>
<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Last but not least, create an aidl file
-that declares your parcelable class (as shown below). If you are using a custom build process,
-do not add the aidl file to your build. Similar to a header file in C, the aidl file isn't
-compiled.</li>
+<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
+{@code Rect.aidl} file, below).
+ <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
+build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
</ol>
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
+<p>AIDL uses these methods and fields in the code it generates to marshall and unmarshall
your objects.</p>
-<p>Here is an example of how the {@link android.graphics.Rect} class implements the
-Parcelable protocol.</p>
-<pre class="prettyprint">
+<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
+parcelable:</p>
+
+<pre>
+package android.graphics;
+
+// Declare Rect so AIDL can find it and knows that it implements
+// the parcelable protocol.
+parcelable Rect;
+</pre>
+
+<p>And here is an example of how the {@link android.graphics.Rect} class implements the
+{@link android.os.Parcelable} protocol.</p>
+
+<pre>
import android.os.Parcel;
import android.os.Parcelable;
@@ -218,7 +376,8 @@
public int right;
public int bottom;
- public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
+ public static final Parcelable.Creator<Rect> CREATOR = new
+Parcelable.Creator<Rect>() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
@@ -251,43 +410,42 @@
}
</pre>
-<p>Here is Rect.aidl for this example</p>
-
-<pre class="prettyprint">
-package android.graphics;
-
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-
-<p>The marshalling in the Rect class is pretty simple. Take a look at the other
+<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
methods on {@link android.os.Parcel} to see the other kinds of values you can write
to a Parcel.</p>
-<p class="warning"><b>Warning:</b> Don't forget the security implications of receiving data from
-other processes. In this case, the rect will read four numbers from the parcel,
-but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See
-<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-on how to keep your application secure from malware.</p>
+<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
+data from other processes. In this case, the {@code Rect} reads four numbers from the {@link
+android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
+values for whatever the caller is trying to do. See <a
+href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
+information about how to keep your application secure from malware.</p>
-<h2 id="calling">Calling an IPC Method</h2>
-<p>Here are the steps a calling class should make to call your remote interface: </p>
+
+
+<h2 id="Calling">Calling an IPC Method</h2>
+
+<p>Here are the steps a calling class must take to call a remote interface defined with AIDL: </p>
<ol>
- <li>Declare a variable of the interface type that your .aidl file defined. </li>
+ <li>Include the {@code .aidl} file in the project {@code src/} directory.</li>
+ <li>Declare an instance of the {@link android.os.IBinder} interface (generated based on the
+AIDL). </li>
<li>Implement {@link android.content.ServiceConnection ServiceConnection}. </li>
- <li>Call {@link android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
- Context.bindService()}, passing in your ServiceConnection implementation. </li>
- <li>In your implementation of {@link android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder)
- ServiceConnection.onServiceConnected()}, you will receive an {@link android.os.IBinder
- IBinder} instance (called <em>service</em>). Call <code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
+ <li>Call {@link
+android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
+ Context.bindService()}, passing in your {@link
+android.content.ServiceConnection} implementation. </li>
+ <li>In your implementation of {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()},
+you will receive an {@link android.os.IBinder} instance (called <code>service</code>). Call
+<code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
cast the returned parameter to <em>YourInterface</em> type.</li>
<li>Call the methods that you defined on your interface. You should always trap
{@link android.os.DeadObjectException} exceptions, which are thrown when
the connection has broken; this will be the only exception thrown by remote
methods.</li>
- <li>To disconnect, call {@link android.content.Context#unbindService(android.content.ServiceConnection)
+ <li>To disconnect, call {@link
+android.content.Context#unbindService(android.content.ServiceConnection)
Context.unbindService()} with the instance of your interface. </li>
</ol>
<p>A few comments on calling an IPC service:</p>
@@ -296,10 +454,12 @@
<li>You can send anonymous objects
as method arguments. </li>
</ul>
+
+<p>For more information about binding to a service, read the <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binding">Bound Services</a>
+document.</p>
+
<p>Here is some sample code demonstrating calling an AIDL-created service, taken
from the Remote Service sample in the ApiDemos project.</p>
<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
calling_a_service}</p>
-
-
-
diff --git a/docs/html/guide/developing/tools/android.jd b/docs/html/guide/developing/tools/android.jd
index 15cf8e0..a67012f 100644
--- a/docs/html/guide/developing/tools/android.jd
+++ b/docs/html/guide/developing/tools/android.jd
@@ -1,4 +1,6 @@
page.title=android
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>{@code android} is an important development tool that lets you:</p>
diff --git a/docs/html/guide/developing/tools/bmgr.jd b/docs/html/guide/developing/tools/bmgr.jd
index 57deb25..d63dcf2 100644
--- a/docs/html/guide/developing/tools/bmgr.jd
+++ b/docs/html/guide/developing/tools/bmgr.jd
@@ -1,4 +1,6 @@
page.title=bmgr
+parent.title=Tools
+parent.link=index.html
@jd:body
<!-- quickview box content here -->
diff --git a/docs/html/guide/developing/tools/dmtracedump.jd b/docs/html/guide/developing/tools/dmtracedump.jd
index 492a049..cb9ad26 100644
--- a/docs/html/guide/developing/tools/dmtracedump.jd
+++ b/docs/html/guide/developing/tools/dmtracedump.jd
@@ -1,4 +1,6 @@
page.title=dmtracedump
+parent.title=Tools
+parent.link=index.html
@jd:body
diff --git a/docs/html/guide/developing/tools/draw9patch.jd b/docs/html/guide/developing/tools/draw9patch.jd
index 4d8043b..1d9de4f 100644
--- a/docs/html/guide/developing/tools/draw9patch.jd
+++ b/docs/html/guide/developing/tools/draw9patch.jd
@@ -1,4 +1,6 @@
page.title=Draw 9-patch
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>The Draw 9-patch tool allows you to easily create a
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index 748a8b1..ff667f2 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -1,6 +1,8 @@
page.title=Android Emulator
+parent.title=Tools
+parent.link=index.html
@jd:body
-<p>
+
<p>The Android SDK includes a mobile device emulator — a virtual mobile device
that runs on your computer. The emulator lets you develop and test
Android applications without using a physical device.</p>
diff --git a/docs/html/guide/developing/tools/hierarchy-viewer.jd b/docs/html/guide/developing/tools/hierarchy-viewer.jd
index ce660fc..3d3191b 100644
--- a/docs/html/guide/developing/tools/hierarchy-viewer.jd
+++ b/docs/html/guide/developing/tools/hierarchy-viewer.jd
@@ -1,4 +1,6 @@
page.title=Hierarchy Viewer
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>Hierarchy Viewer allows you to debug and optimize your user
diff --git a/docs/html/guide/developing/tools/hprof-conv.jd b/docs/html/guide/developing/tools/hprof-conv.jd
index 27000b4..f96def2 100644
--- a/docs/html/guide/developing/tools/hprof-conv.jd
+++ b/docs/html/guide/developing/tools/hprof-conv.jd
@@ -1,4 +1,6 @@
page.title=HPROF Converter
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>
diff --git a/docs/html/guide/developing/tools/layoutopt.jd b/docs/html/guide/developing/tools/layoutopt.jd
index e8f623d..cb0b505 100644
--- a/docs/html/guide/developing/tools/layoutopt.jd
+++ b/docs/html/guide/developing/tools/layoutopt.jd
@@ -1,4 +1,6 @@
page.title=layoutopt
+parent.title=Tools
+parent.link=index.html
@jd:body
<p><code>layoutopt</code> is a command-line tool that helps you optimize the
diff --git a/docs/html/guide/developing/tools/logcat.jd b/docs/html/guide/developing/tools/logcat.jd
index 9603b9f..d4ee68a 100644
--- a/docs/html/guide/developing/tools/logcat.jd
+++ b/docs/html/guide/developing/tools/logcat.jd
@@ -1,4 +1,6 @@
page.title=logcat
+parent.title=Tools
+parent.link=index.html
@jd:body
<div></div>
diff --git a/docs/html/guide/developing/tools/mksdcard.jd b/docs/html/guide/developing/tools/mksdcard.jd
index 0ec69d2..0a80454 100644
--- a/docs/html/guide/developing/tools/mksdcard.jd
+++ b/docs/html/guide/developing/tools/mksdcard.jd
@@ -1,4 +1,6 @@
page.title=mksdcard
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>The <code>mksdcard</code> tool lets you quickly create a FAT32 disk image that you can load in the
diff --git a/docs/html/guide/developing/tools/monkey.jd b/docs/html/guide/developing/tools/monkey.jd
index 6c05934..a7e539c 100644
--- a/docs/html/guide/developing/tools/monkey.jd
+++ b/docs/html/guide/developing/tools/monkey.jd
@@ -1,4 +1,6 @@
page.title=UI/Application Exerciser Monkey
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>The Monkey is a program that runs on your
diff --git a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
index 658ff75..97c7c1f 100644
--- a/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
+++ b/docs/html/guide/developing/tools/monkeyrunner_concepts.jd
@@ -1,4 +1,6 @@
page.title=monkeyrunner
+parent.title=Tools
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/tools/proguard.jd b/docs/html/guide/developing/tools/proguard.jd
index e75a8cd..b97babe 100644
--- a/docs/html/guide/developing/tools/proguard.jd
+++ b/docs/html/guide/developing/tools/proguard.jd
@@ -1,4 +1,6 @@
page.title=ProGuard
+parent.title=Tools
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/developing/tools/sqlite3.jd b/docs/html/guide/developing/tools/sqlite3.jd
index 71e614f..9cc7e98 100644
--- a/docs/html/guide/developing/tools/sqlite3.jd
+++ b/docs/html/guide/developing/tools/sqlite3.jd
@@ -1,4 +1,6 @@
page.title=sqlite3
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>From a remote shell to your device or from your host machine, you can use the <a href=
diff --git a/docs/html/guide/developing/tools/traceview.jd b/docs/html/guide/developing/tools/traceview.jd
index 422fe00..aa37481 100644
--- a/docs/html/guide/developing/tools/traceview.jd
+++ b/docs/html/guide/developing/tools/traceview.jd
@@ -1,4 +1,6 @@
page.title=Traceview
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>Traceview is a graphical viewer for execution logs saved by your application.
diff --git a/docs/html/guide/developing/tools/zipalign.jd b/docs/html/guide/developing/tools/zipalign.jd
index 6231798..ebf177b 100644
--- a/docs/html/guide/developing/tools/zipalign.jd
+++ b/docs/html/guide/developing/tools/zipalign.jd
@@ -1,4 +1,6 @@
page.title=zipalign
+parent.title=Tools
+parent.link=index.html
@jd:body
<p>zipalign is an archive alignment tool that provides important
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 24ccfdb..d81b416 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -60,27 +60,27 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/fundamentals/activities.html">
<span class="en">Activities</span>
- </a></div>
+ </a> <span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/fragments.html">
<span class="en">Fragments</span>
</a> <span class="new">new!</span></li>
- <li><a href="<?cs var:toroot ?>guide/topics/providers/loaders.html">
+ <li><a href="<?cs var:toroot ?>guide/topics/fundamentals/loaders.html">
<span class="en">Loaders</span>
- </a><span class="new">new!</span></li>
+ </a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/tasks-and-back-stack.html">
<span class="en">Tasks and Back Stack</span>
- </a></li>
+ </a> <span class="new">new!</span></li>
</ul>
</li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/fundamentals/services.html">
<span class="en">Services</span>
- </a></div>
+ </a> <span class="new">new!</span></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/bound-services.html">
<span class="en">Bound Services</span>
- </a></li>
+ </a> <span class="new">new!</span></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/providers/content-providers.html">
@@ -91,7 +91,7 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/processes-and-threads.html">
<span class="en">Processes and Threads</span>
- </a></li>
+ </a> <span class="new">new!</span></li>
</ul>
@@ -419,7 +419,7 @@
<li class="toggle-list">
<div>
<a href="<?cs var:toroot ?>guide/developing/devices/index.html">
- <span class="en">Creating and Managing Virtual Devices</span>
+ <span class="en">Managing Virtual Devices</span>
</a>
</div>
<ul>
@@ -430,7 +430,7 @@
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/devices/managing-avds-cmdline.html">
- <span class="en">On the Command Line</span>
+ <span class="en">From the Command Line</span>
</a>
</li>
<li>
@@ -460,7 +460,7 @@
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/projects/projects-cmdline.html">
- <span class="en">On the Command Line</span>
+ <span class="en">From the Command Line</span>
</a>
</li>
</ul>
@@ -490,12 +490,12 @@
<ul>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-projects.html">
- <span class="en">In Eclipse with ADT</span>
+ <span class="en">From Eclipse with ADT</span>
</a>
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-projects-cmdline.html">
- <span class="en">In Other IDEs</span>
+ <span class="en">From Other IDEs</span>
</a>
</li>
<li>
@@ -505,7 +505,7 @@
</li>
<li>
<a href="<?cs var:toroot ?>guide/developing/debugging/debugging-log.html">
- <span class="en">Reading and Writing Log Messages</span>
+ <span class="en">Reading and Writing Logs</span>
</a>
</li>
<li>
@@ -554,7 +554,6 @@
<ul>
<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/android.html">android</a></li>
- <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
<li><a href="<?cs var:toroot ?>guide/developing/tools/dmtracedump.html">dmtracedump</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html" >Draw 9-Patch</a></li>
@@ -754,6 +753,7 @@
<li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
<span class="en">Intents List: Google Apps</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">AIDL</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/glossary.html">
<span class="en">Glossary</span>
</a></li>
diff --git a/docs/html/guide/market/billing/billing_about.jd b/docs/html/guide/market/billing/billing_about.jd
index 9c027ca..dac9738 100755
--- a/docs/html/guide/market/billing/billing_about.jd
+++ b/docs/html/guide/market/billing/billing_about.jd
@@ -1,4 +1,6 @@
page.title=About this Release
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_admin.jd b/docs/html/guide/market/billing/billing_admin.jd
index cc5cb59..cd8f960 100755
--- a/docs/html/guide/market/billing/billing_admin.jd
+++ b/docs/html/guide/market/billing/billing_admin.jd
@@ -1,4 +1,6 @@
page.title=Administering In-app Billing
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_best_practices.jd b/docs/html/guide/market/billing/billing_best_practices.jd
index fd67e80..4743e88 100755
--- a/docs/html/guide/market/billing/billing_best_practices.jd
+++ b/docs/html/guide/market/billing/billing_best_practices.jd
@@ -1,4 +1,6 @@
page.title=Security and Design
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_integrate.jd b/docs/html/guide/market/billing/billing_integrate.jd
index 0f081a5..0cac2eb 100755
--- a/docs/html/guide/market/billing/billing_integrate.jd
+++ b/docs/html/guide/market/billing/billing_integrate.jd
@@ -1,4 +1,6 @@
page.title=Implementing In-app Billing
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_overview.jd b/docs/html/guide/market/billing/billing_overview.jd
index 675fe2a..b899b9b 100755
--- a/docs/html/guide/market/billing/billing_overview.jd
+++ b/docs/html/guide/market/billing/billing_overview.jd
@@ -1,4 +1,6 @@
-page.title=Overview of In-app Billing
+page.title=In-app Billing Overview
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_reference.jd b/docs/html/guide/market/billing/billing_reference.jd
index c91ca89..2e5c9c6 100755
--- a/docs/html/guide/market/billing/billing_reference.jd
+++ b/docs/html/guide/market/billing/billing_reference.jd
@@ -1,4 +1,6 @@
page.title=In-app Billing Reference
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/billing_testing.jd b/docs/html/guide/market/billing/billing_testing.jd
index 4a36588..5ced9c7 100755
--- a/docs/html/guide/market/billing/billing_testing.jd
+++ b/docs/html/guide/market/billing/billing_testing.jd
@@ -1,4 +1,6 @@
page.title=Testing In-app Billing
+parent.title=In-app Billing
+parent.link=index.html
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/market/billing/index.jd b/docs/html/guide/market/billing/index.jd
index f5d001d..6985179 100755
--- a/docs/html/guide/market/billing/index.jd
+++ b/docs/html/guide/market/billing/index.jd
@@ -1,4 +1,4 @@
-page.title=Adding In-app Billing to Your Applications
+page.title=In-app Billing
@jd:body
<style type="text/css">
diff --git a/docs/html/guide/publishing/licensing.jd b/docs/html/guide/publishing/licensing.jd
index 5551384..4184ecb 100644
--- a/docs/html/guide/publishing/licensing.jd
+++ b/docs/html/guide/publishing/licensing.jd
@@ -1,4 +1,4 @@
-page.title=Licensing Your Applications
+page.title=Application Licensing
@jd:body
<div id="qv-wrapper">
@@ -518,7 +518,7 @@
</ol>
<p>If you are not familiar with AVDs or how to use them, see <a
-href="{@docRoot}guide/developing/devices/index.html">Creating and Managing Virtual Devices</a>.</p>
+href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a>.</p>
<h4 id="project-update">Updating your project configuration</h4>
@@ -629,7 +629,7 @@
<p style="margin-top:.5em;">If you aren't familiar with library projects or how
to use them, see <a href="{@docRoot}guide/developing/projects/index.html#LibraryProjects">
-Creating and Managing Projects</a>.
+Managing Projects</a>.
</p>
</div>
</div>
@@ -666,8 +666,9 @@
no further configuration is needed. </p>
<p>For more information about how to create an application project or work with
-library projects in Eclipse, see <a href="{@docRoot}guide/developing/projects/projects-eclipse.html">
-Creating and Managing Projects in Eclipse</a></p>.
+library projects in Eclipse, see <a
+href="{@docRoot}guide/developing/projects/projects-eclipse.html">Managing Projects from
+Eclipse with ADT</a></p>.
<h4>Copying the LVL sources to your application</h4>
@@ -698,8 +699,8 @@
Select the "Android" properties group and click <strong>Add</strong>, then
choose the LVL library project (com_android_vending_licensing) and click
<strong>OK</strong>. For more information, see
-<a href="{@docRoot}developing/projects/projects-eclipse.html#SettingUpLibraryProject">
-Creating and Managing Projects in Eclipse</a></p>.
+<a href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">
+Managing Projects from Eclipse with ADT</a></p>.
<div style="margin-bottom:2em;">
@@ -727,8 +728,8 @@
</pre>
<p>For more information about working with library projects,
-see <a href="{@docRoot}developing/projects/projects-cmdline.html#SettingUpLibraryProject">
-Creating and Managing Projects on the Command Line</a></p>.
+see <a href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">
+Managing Projects from the Command Line</a></p>.
<h2 id="app-integration">Integrating the LVL with Your Application</h2>
diff --git a/docs/html/guide/topics/advanced/aidl.jd b/docs/html/guide/topics/advanced/aidl.jd
deleted file mode 100644
index fef46ec..0000000
--- a/docs/html/guide/topics/advanced/aidl.jd
+++ /dev/null
@@ -1,387 +0,0 @@
-page.title=Android Interface Definition Language (AIDL)
-@jd:body
-
-
-
-<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
-worked with. It allows you to define the programming interface that both
-the client and service agree upon in order to communicate with each other and allows for
-interprocess communication (IPC). On Android, one process can not normally access the
-memory of another process. So to talk, they need to decompose their objects into primitives that the
-operating system can understand, and "marshall" the object across that boundary for you. The code to
-do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
-
-<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
-different applications to access your service for IPC and want to handle multithreading in your
-service. If you do not need to perform IPC across
-different applications, you should create your interface <a href="Binder">implementing a
-Binder</a> or, if you want to perform IPC, but do not need to handle multithreading, then you
-should implement your interface <a href="#Messenger">using a Messenger</a>.</p>
-
-<p>Before you begin designing your AIDL interface, be aware that calls on to an AIDL interface are
-direct function calls. You can not generally make assumptions about the thread in which the call
-will happen. What happens is different depending on whether the call is from a thread in the
-local process, or coming from a remote process. Specifically:</p>
-
-<ul>
-<li>Calls from the local process are executed in the same thread that is making the call. If this is
-your main UI thread, that thread will continue executing into the aidl interface. If it is another
-thread, that is one that will be executing your code. Thus if only local threads are accessing the
-interface, you can completely control which threads are executing in it (but if that is the case,
-why are you defining an aidl interface at all?).</li>
-
-<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
-your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
-happening at the same time. In other words, an implementation of an aidl interface must be
-completely thread-safe.</li>
-
-<li>The "oneway" keyword modifies the behavior of remote calls. When used, a remote call will not
-block until its call completes; it simply sends the transaction data and immediately returns. The
-implementation of the interface will eventually receive this as a regular call from the {@link
-android.os.Binder} thread pool as a normal remote call. If "oneway" is used with a local call,
-there is no impact and the call is still synchronous.</li>
-</ul>
-
-
-<h2 id="Defining">Defining an AIDL Interface</h2>
-
-<p>You must define your AIDL interface in an {@code .aidl} file using the Java
-programming language syntax, then save it in the source code (in the {@code src/} directory) of both
-the application hosting the service and any other application that will bind to the service.</p>
-
-<p>When you build the projects containing the {@code .aidl} file, the Android SDK tools generate an
-{@link android.os.IBinder} class based on your AIDL interface (and saves the file in the {@code
-gen/} directory). This class defines the APIs you can call to perform RPC as an interface—you
-must implement the interface in your service.</p>
-
-<p>To create a bounded service using AIDL, follow these steps:</p>
-<ol>
- <li><a href="#CreateAidl">Create the .aidl file</a>
- <p>This file defines the programming interface with method signatures.</p>
- </li>
- <li><a href="#ImplementTheInterface">Implement the interface</a>
- <p>The Android SDK tools generate an interface in the Java programming language, based on your
-{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
-{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
-{@code Stub} class and implement the methods.</p>
- </li>
- <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
- <p>Implement a {@link android.app.Service Service} and override {@link
-android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
-class.</p>
- </li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
-your first release must remain backward compatible in order to avoid breaking other applications
-that use your service. That is, because your {@code .aidl} file must be copied to other applications
-in order for them to access your service's interface, you must maintain support for the original
-interface.</p>
-
-
-<h3 id="CreateAidl">1. Create the .aidl file</h3>
-
-<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
-take parameters and return values. The parameters and return values can be of any type, even other
-AIDL-generated interfaces.</p>
-
-<p>The syntax for the {@code .aidl} file uses the Java programming language. The file defines a
-single interface and requires only the interface declaration and method signatures.</p>
-
-<p>By default, AIDL supports the following data types:</p>
-
-<ul>
- <li>All primitive types in the Java programming language ({@code int}, {@code long}, {@code
-char}, {@code boolean}, etc.)</li>
- <li>{@link java.lang.String}</li>
- <li>{@link java.lang.CharSequence}</li>
- <li>{@link java.util.List}
- <p>All elements in the {@link java.util.List} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
-java.util.List} may optionally be used as a "generic" class (e.g. <code>List<String></code>).
-The actual concrete class that the other side will receive will always be an {@link
-java.util.ArrayList}, although the method will be generated to use the {@link
-java.util.List} interface.</p>
- </li>
- <li>{@link java.util.Map}
- <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
-(such as those of the form
-{@code Map<String,Integer>} are not supported. The actual concrete class that the other side
-will receive will always be a {@link java.util.HashMap}, although the method will be generated to
-use the {@link java.util.Map} interface.</p>
- </li>
-</ul>
-
-<p>You must include an {@code import} statement for each additional type not listed above, even if
-they are defined in the same package as your interface.</p>
-
-<p>When defining methods for your service interface, be aware that:</p>
-<ul>
- <li>Methods can take zero or more parameters, and return a value or void.</li>
- <li>All non-primitive parameters require a directional tag indicating which way the data will go.
-Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
- <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
- <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
-needed, because marshalling parameters is expensive.</p></li>
- <li>All code comments included in the {@code .aidl} file are included in the generated {@link
-android.os.IBinder} interface (except for comments before the import and package
-statements).</li>
-</ul>
-
-<p>Here is an example {@code .aidl} file:</p>
-
-<pre>
-// IRemoteService.aidl
-package com.example.android;
-
-// Declare any non-default types here with import statements
-
-/** Example service interface */
-interface IRemoteService {
- /** Request the process ID of this service, to do evil things with it. */
- int getPid();
-
- /** Demonstrates some basic types that you can use as parameters
- * and return values in AIDL.
- */
- void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
- double aDouble, String aString);
-}
-</pre>
-
-<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
-build your application, the SDK tools will generate the binder class file in your project's
-{@code gen/} directory. The generated file name matches the {@code .aidl} file name, but with a
-{@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
-IRemoteService.java}).</p>
-
-<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
-do not use Eclipse, then the Ant tool generates the binder class next time you build your
-application—you should build your project with <code>ant debug</code> (or <code>ant
-release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
-link against the generated class.</p>
-
-
-<h3 id="ImplementTheInterface">2. Implement the interface</h3>
-
-<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
-named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
-that is an abstract implementation of its parent interface (for example, {@code
-YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
-
-<p class="note"><strong>Note:</strong> {@code Stub} also
-defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
-android.os.IBinder} (usually the one passed to a client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
-returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
-Method</a> for more details on how to make this cast.</p></p>
-
-<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
-android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
-inherited from the {@code .aidl} file.</p>
-
-<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
-{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
-
-<pre>
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
-};
-</pre>
-
-<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
-which defines the RPC interface for the service. In the next step, this instance is exposed to
-clients so they can interact with the service.</p>
-
-<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
-<ul>
- <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
-about multithreading from the start and properly build your service to be thread-safe.</li>
- <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
-milliseconds to complete a request, you should not call it from the activity's main thread, because
-it might hang the application (Android might display an "Application is Not Responding"
-dialog)—you should usually call them from a separate thread in the client. </li>
- <li>No exceptions that you throw are sent back to the caller.</li>
- <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
-</ul>
-
-
-<h3 id="ExposeTheInterface">3. Expose the interface to clients</h3>
-
-<p>Once you've implemented the interface for your service, you need to expose it to
-clients so they can bind to it. To expose the interface
-for your service, extend {@link android.app.Service Service} and implement {@link
-android.app.Service#onBind onBind()} to return an instance of your class that implements
-the generated {@code Stub} (as discussed in the previous section). Here's an example
-service that exposes the {@code IRemoteService} example interface to clients. </p>
-
-<pre>
-public class RemoteService extends Service {
- @Override
- public void onCreate() {
- super.onCreate();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- // Return the interface
- return mBinder;
- }
-
- private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
- };
-}
-</pre>
-
-<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
-bindService()} to connect to this service, the client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
-{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
-method.</p>
-
-<p>The client must also have access to the interface class, so if the client and service are in
-separate applications, then the client's application must have a copy of the {@code .aidl} file
-in its {@code src/} directory (which generates the {@code android.os.Binder}
-interface—providing the client access to the AIDL methods).</p>
-
-<p>When the client receives the {@link android.os.IBinder} in the {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
-<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
-parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
-
-<pre>
-IRemoteService mIRemoteService;
-private ServiceConnection mConnection = new ServiceConnection() {
- // Called when the connection with the service is established
- public void onServiceConnected(ComponentName className, IBinder service) {
- // Following the example above for an AIDL interface,
- // this gets an instance of the IRemoteInterface, which we can use to call on the service
- mIRemoteService = IRemoteService.Stub.asInterface(service);
- }
-
- // Called when the connection with the service disconnects unexpectedly
- public void onServiceDisconnected(ComponentName className) {
- Log.e(TAG, "onServiceDisconnected");
- }
-};
-</pre>
-
-<p>For more sample code, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
-RemoteService.java}</a> class in <a
-href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
-
-
-
-
-
-
-
-
-<h2 id="PassingObjects">Passing Objects over IPC</h2>
-
-<p>If you have a class that you would like to send from one process to another through
-an IPC interface, you can do that. However, you must ensure that the code for your class is
-available to the other side of the IPC and the class must support the {@link
-android.os.Parcelable} interface, in order for the objects to be decomposed into primitives and
-marshalled across processes by the Android system.</p>
-
-<p>There are five parts to making a class support the {@link android.os.Parcelable} protocol:</b>
-<ol>
-<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
-current state of the object and writes it to a {@link android.os.Parcel}.</li>
-<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
-the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
-{@code Rect.aidl} file, below).
- <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
-build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
-</ol>
-
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
-your objects.</p>
-
-<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
-parcelable:</p>
-
-<pre>
-package android.graphics;
-
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-
-<p>And here is an example of how the {@link android.graphics.Rect} class implements the
-{@link android.os.Parcelable} protocol.</p>
-
-<pre>
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class Rect implements Parcelable {
- public int left;
- public int top;
- public int right;
- public int bottom;
-
- public static final Parcelable.Creator<Rect> CREATOR = new
-Parcelable.Creator<Rect>() {
- public Rect createFromParcel(Parcel in) {
- return new Rect(in);
- }
-
- public Rect[] newArray(int size) {
- return new Rect[size];
- }
- };
-
- public Rect() {
- }
-
- private Rect(Parcel in) {
- readFromParcel(in);
- }
-
- public void writeToParcel(Parcel out) {
- out.writeInt(left);
- out.writeInt(top);
- out.writeInt(right);
- out.writeInt(bottom);
- }
-
- public void readFromParcel(Parcel in) {
- left = in.readInt();
- top = in.readInt();
- right = in.readInt();
- bottom = in.readInt();
- }
-}
-</pre>
-
-<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
-methods on {@link android.os.Parcel} to see the other kinds of values you can write
-to a Parcel.</p>
-
-<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
-data from other processes. In this case, the {@code Rect} will read four numbers from the {@link
-android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See <a
-href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-information about how to keep your application secure from malware.</p>
-
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd
index 3fdbd95..661f5cb 100644
--- a/docs/html/guide/topics/fundamentals.jd
+++ b/docs/html/guide/topics/fundamentals.jd
@@ -422,7 +422,7 @@
resources. However, you should create specialized layouts for certain screen sizes and provide
specialized images for certain densities, using alternative layout resources, and by declaring in
your manifest exactly which screen sizes your application supports with the <a
-href="{@docRoot}guide/topics/manifest/supports-screens.html">{@code
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
<supports-screens>}</a> element.</p>
<p>For more information, see the <a
href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>
@@ -453,7 +453,8 @@
href="{@docRoot}guide/appendix/api-levels.html">API Level</a> (for example, Android 1.0 is API Level
1 and Android 2.3 is API Level 9). If you use any APIs that were added to the platform after
version 1.0, you should declare the minimum API Level in which those APIs were introduced using the
-<a href="{@docRoot}guide/topics/manifest/uses-sdk.html">{@code <uses-sdk>}</a> element.</dd>
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a>
+element.</dd>
</dl>
<p>It's important that you declare all such requirements for your application, because, when you
diff --git a/docs/html/guide/topics/fundamentals/activities.jd b/docs/html/guide/topics/fundamentals/activities.jd
index 9079ef6..5cc1b45 100644
--- a/docs/html/guide/topics/fundamentals/activities.jd
+++ b/docs/html/guide/topics/fundamentals/activities.jd
@@ -40,7 +40,7 @@
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a></li>
- <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack">Tasks and Back
+ <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
Stack</a></li>
</ol>
@@ -594,13 +594,14 @@
definition in table 1 might still be killed by the system—but that would happen only in
extreme circumstances when there is no other recourse. When an activity might be killed is
discussed more in the <a
-href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html">Processes and
+href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
Threading</a> document.</p>
<h3 id="SavingActivityState">Saving activity state</h3>
-<p>The introduction to <a href="Lifecycle">Managing the Activity Lifecycle</a> briefly mentions that
+<p>The introduction to <a href="#Lifecycle">Managing the Activity Lifecycle</a> briefly mentions
+that
when an activity is paused or stopped, the state of the activity is retained. This is true because
the {@link android.app.Activity} object is still held in memory when it is paused or
stopped—all information about its members and current state is still alive. Thus, any changes
diff --git a/docs/html/guide/topics/fundamentals/bound-services.jd b/docs/html/guide/topics/fundamentals/bound-services.jd
index e5d626c..ec7d723 100644
--- a/docs/html/guide/topics/fundamentals/bound-services.jd
+++ b/docs/html/guide/topics/fundamentals/bound-services.jd
@@ -170,7 +170,7 @@
create a bound service, because it may require multithreading capabilities and
can result in a more complicated implementation. As such, AIDL is not suitable for most applications
and this document does not discuss how to use it for your service. If you're certain that you need
-to use AIDL directly, see the <a href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a>
+to use AIDL directly, see the <a href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a>
document.</p>
@@ -341,7 +341,7 @@
<p>For most applications, the service doesn't need to perform multi-threading, so using a {@link
android.os.Messenger} allows the service to handle one call at a time. If it's important
that your service be multi-threaded, then you should use <a
-href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a> to define your interface.</p>
+href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> to define your interface.</p>
</div>
</div>
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index 7ca990e..f780960 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -743,7 +743,8 @@
based on the screen configuration.</p>
<p class="note"><strong>Note:</strong> The complete source code for this activity is available in
-<a href="resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
+<a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
FragmentLayout.java}</a>.</p>
<p>The main activity applies a layout in the usual way, during {@link
diff --git a/docs/html/guide/topics/providers/loaders.jd b/docs/html/guide/topics/fundamentals/loaders.jd
similarity index 97%
rename from docs/html/guide/topics/providers/loaders.jd
rename to docs/html/guide/topics/fundamentals/loaders.jd
index c54656c..d31f090 100644
--- a/docs/html/guide/topics/providers/loaders.jd
+++ b/docs/html/guide/topics/fundamentals/loaders.jd
@@ -1,4 +1,6 @@
-page.title=Using Loaders
+page.title=Loaders
+parent.title=Activities
+parent.link=activities.html
@jd:body
<div id="qv-wrapper">
<div id="qv">
@@ -29,8 +31,11 @@
<h2>Related samples</h2>
<ol>
- <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentCursorLoader.html"> FragmentCursorLoader</a></li>
- <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a></li>
+ <li> <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">FragmentListCursorLoader</a></li>
+ <li> <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+LoaderThrottle</a></li>
</ol>
</div>
</div>
@@ -480,7 +485,7 @@
<p>There are a few different samples in <strong>ApiDemos</strong> that
illustrate how to use loaders:</p>
<ul>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentCursorLoader.html"> FragmentCursorLoader</a> — A complete version of the
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">FragmentListCursorLoader</a> — A complete version of the
snippet shown above.</li>
<li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — An example of how to use throttling to
reduce the number of queries a content provider does then its data changes.</li>
diff --git a/docs/html/guide/topics/fundamentals/services.jd b/docs/html/guide/topics/fundamentals/services.jd
index d0c924a..a9dd315 100644
--- a/docs/html/guide/topics/fundamentals/services.jd
+++ b/docs/html/guide/topics/fundamentals/services.jd
@@ -121,7 +121,7 @@
android.app.Activity#onStart onStart()}, then stop it in {@link android.app.Activity#onStop
onStop()}. Also consider using {@link android.os.AsyncTask} or {@link android.os.HandlerThread},
instead of the traditional {@link java.lang.Thread} class. See the <a
-href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html#Threads">Processes and
+href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes and
Threading</a> document for more information about threads.</p>
<p>Remember that if you do use a service, it still runs in your application's main thread by
default, so you should still create a new thread within the service if it performs intensive or
@@ -183,7 +183,7 @@
available again (though this also depends on the value you return from {@link
android.app.Service#onStartCommand onStartCommand()}, as discussed later). For more information
about when the system might destroy a service, see the <a
-href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html">Processes and Threading</a>
+href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and Threading</a>
document.</p>
<p>In the following sections, you'll see how you can create each type of service and how to use
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 6594568..618cdf8 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -1,5 +1,5 @@
page.title=2D Graphics
-parent.title=2D and 3D Graphics
+parent.title=Graphics
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
index cd74efa..3b1716c 100644
--- a/docs/html/guide/topics/graphics/animation.jd
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -1,4 +1,6 @@
page.title=Property Animation
+parent.title=Graphics
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index 4d0b223..1f51c2d 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -1,5 +1,5 @@
page.title=3D with OpenGL
-parent.title=2D and 3D Graphics
+parent.title=Graphics
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/graphics/renderscript.jd b/docs/html/guide/topics/graphics/renderscript.jd
index 0ef8a22..0e64c78 100644
--- a/docs/html/guide/topics/graphics/renderscript.jd
+++ b/docs/html/guide/topics/graphics/renderscript.jd
@@ -1,4 +1,6 @@
page.title=3D Rendering and Computation with Renderscript
+parent.title=Graphics
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
@@ -14,7 +16,7 @@
<ol>
<li><a href="#native-api">Native Renderscript APIs</a></li>
- <li><a href="#reflective-api">Reflective layer APIs</a></li>
+ <li><a href="#reflective-api">Reflected layer APIs</a></li>
<li><a href="#graphics-api">Graphics APIs</a></li>
</ol>
@@ -28,10 +30,18 @@
</ol>
</li>
</ol>
+ <h2>Related Samples</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Balls/index.html">Balls</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Fountain/index.html">Fountain</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/HelloCompute/index.html">Hello Compute</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/HelloWorld/index.html">Hello World</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Samples/index.html">Samples</a></li>
+ </ol>
</div>
</div>
- <p>The Renderscript system offers high performance 3D rendering and mathematical computations at
+ <p>The Renderscript system offers high performance 3D rendering and mathematical computation at
the native level. The Renderscript APIs are intended for developers who are comfortable with
developing in C (C99 standard) and want to maximize performance in their applications. The
Renderscript system improves performance by running as native code on the device, but it also
@@ -44,47 +54,46 @@
intermediate code.</p>
<p>The disadvantage of the Renderscript system is that it adds complexity to the development and
- debugging processes and is not a substitute for the Android system APIs. It is a portable native
- language with pointers and explicit resource management. The target use is for performance
- critical code where the existing Android APIs are not sufficient. If what you are rendering or
- computing is very simple and does not require much processing power, you should still use the
- Android APIs for ease of development. Debugging visibility can be limited, because the
+ debugging processes. Debugging visibility can be limited, because the
Renderscript system can execute on processors other than the main CPU (such as the GPU), so if
- this occurs, debugging becomes more difficult. Remember the tradeoffs between development and
- debugging complexity versus performance when deciding to use Renderscript.</p>
+ this occurs, debugging becomes more difficult. The target use is for performance
+ critical code where the traditional framework APIs (such as using {@link android.opengl}) are not sufficient.
+ If what you are rendering or computing is very simple and does not require much processing power, you should still use the
+ traditional framework APIs for ease of development. Remember the tradeoffs between development and
+ debugging complexity versus performance when deciding to use Renderscript. </p>
<p>For an example of Renderscript in action, see the 3D carousel view in the Android 3.0 versions
of Google Books and YouTube or install the Renderscript sample applications that are shipped with
- the SDK in <code><sdk_root>/platforms/android-3.0/samples</code>.</p>
+ the SDK in <code><sdk_root>/samples/android-11/Renderscript</code>.</p>
<h2 id="overview">Renderscript System Overview</h2>
<p>The Renderscript system adopts a control and slave architecture where the low-level native
code is controlled by the higher level Android system that runs in the virtual machine (VM). When
- you use the Renderscript system, there are three layers of APIs that exist:</p>
+ you use the Renderscript system, there are three layers that exist:</p>
<ul>
- <li>The native Renderscript layer consists of the native Renderscript <code>.rs</code> files
- that you write to compute mathematical operations, render graphics, or both. This layer does
- the intensive computation or graphics rendering and returns the result back to the Android VM
- through the reflected layer.</li>
+ <li>The native Renderscript layer consists of native libraries that are packaged with the SDK.
+ The native Renderscript <code>.rs</code> files compute mathematical operations, render graphics,
+ or both. This layer does the intensive computation or graphics rendering and returns the result
+ back to the Android VM through the reflected layer.</li>
- <li>The reflected layer is a set of generated Android system classes (through reflection) based
- on the native layer interface that you define. This layer acts as a bridge between the native
+ <li>The reflected layer is a set of generated Android framework classes reflected from
+ the native Renderscript code that you wrote. This layer acts as a bridge between the native
Renderscript layer and the Android system layer. The Android build tools automatically generate
- the APIs for this layer during the build process.</li>
+ the classes for this layer during the build process. This layer also includes a set of Android
+ framework APIs that provide the memory and resource allocation classes to support this layer.</li>
- <li>The Android system layer consists of your normal Android APIs along with the Renderscript
+ <li>The Android system layer consists of the traditional framework APIs, which include the Renderscript
APIs in {@link android.renderscript}. This layer handles things such as the Activity lifecycle
- management of your application and calls the native Renderscript layer through the reflected
- layer.</li>
+ management of your application and calls the reflected layer to communicate with the native Renderscript code.</li>
</ul>
<p>To fully understand how the Renderscript system works, you must understand how the reflected
layer is generated and how it interacts with the native Renderscript layer and Android system
layer. The reflected layer provides the entry points into the native code, enabling the Android
- system code to give high level commands like, "rotate the view" or "filter the bitmap." It
- delegates all the heavy lifting to the native layer. To accomplish this, you need to create logic
+ system to give high level commands like, "rotate the view" or "filter the bitmap" to the
+ native layer, which does the heavy lifting. To accomplish this, you need to create logic
to hook together all of these layers so that they can correctly communicate.</p>
<p>At the root of everything is your Renderscript, which is the actual C code that you write and
@@ -92,11 +101,10 @@
and graphics. A compute Renderscript does not do any graphics rendering while a graphics
Renderscript does.</p>
- <p>When you create a Renderscript <code>.rs</code> file, an equivalent, reflective layer class,
- {@link android.renderscript.ScriptC}, is generated by the build tools and exposes the native
- functions to the Android system. This class is named
- <code><em>ScriptC_renderscript_filename</em></code>. The following list describes the major
- components of your native Renderscript code that is reflected:</p>
+ <p>When you create Renderscript <code>.rs</code> files, equivalent, reflected classes
+ are generated by the build tools and expose the native functions and data types and structures
+ to the Android system. The following list describes the major components of your native Renderscript
+ code that is reflected:</p>
<ul>
<li>The non-static functions in your Renderscript (<code>.rs</code> file) are reflected into
@@ -106,12 +114,12 @@
<li>Any non-static, global Renderscript variables are reflected into
<code><em>ScriptC_renderscript_filename</em></code>.
Accessor methods are generated, so the Android system layer can access the values.
- The <code>get()</code> method comes with a one-way communication restriction.
- The Android system layer always caches the last value that is set and returns that during a call to get.
- If the native Renderscript code has changed the value, the change does propagate back to the Android system layer
- for efficiency. If the global variables are initialized in the native Renderscript code, those values are used
- to initialize the Android system versions. If global variables are marked as <code>const</code>,
- then a <code>set()</code> method is not generated.
+ The <code>get</code> method comes with a one-way communication restriction.
+ The Android system layer always caches the last value that is set and returns that during a call to a <code>get<code> method.
+ If the native Renderscript code changes the value, the change does not propagate back to the Android system layer.
+ If the global variables are initialized in the native Renderscript code, those values are used
+ to initialize the corresponding values in the Android system. If global variables are marked as <code>const</code>,
+ then a <code>set</code> method is not generated.
</li>
<li>Structs are reflected into their own classes, one for each struct, into a class named
@@ -126,15 +134,14 @@
Renderscripts should not directly set the exported global pointers.</li>
</ul>
- <p>The Android system also has a corresponding Renderscript context object, {@link
+ <p>The Android framework API also has a corresponding Renderscript context object, {@link
android.renderscript.RenderScript} (for a compute Renderscript) or {@link
android.renderscript.RenderScriptGL} (for a graphics Renderscript). This context object allows
you to bind to the reflected Renderscript class, so that the Renderscript context knows what its
corresponding native Renderscript is. If you have a graphics Renderscript context, you can also
specify a variety of Programs (stages in the graphics pipeline) to tweek how your graphics are
rendered. A graphics Renderscript context also needs a surface to render on, {@link
- android.renderscript.RSSurfaceView}, which gets passed into its constructor. When all three of
- the layers are connected, the Renderscript system can compute or render graphics.</p>
+ android.renderscript.RSSurfaceView}, which gets passed into its constructor.</p>
<h2 id="api">API overview</h2>
@@ -143,15 +150,15 @@
because these functions are assumed to be running on a standard CPU. The Renderscript runtime
chooses the best processor to execute the code, which may not be the CPU, so it cannot guarantee
support for standard C libraries. What Renderscript does offer is an API that supports intensive
- computation with an extensive collection of math APIs. Some key features of the Renderscript APIs
- are:</p>
+ computation with an extensive collection of math APIs. The following sections group the APIs
+ into three distinct categories.</p>
<h3 id="native-api">Native Renderscript APIs</h3>
<p>The Renderscript headers are located in the <code>include</code> and
<code>clang-include</code> directories in the
- <code><sdk_root>/platforms/android-3.0/renderscript</code> directory of the Android SDK.
+ <code><sdk_root>/platforms/android-11/renderscript</code> directory of the Android SDK.
The headers are automatically included for you, except for the graphics specific header,
which you can define as follows:</p>
@@ -168,16 +175,14 @@
<li>Graphics rendering functions</li>
<li>Memory allocation request features</li>
<li>Data types and structures to support the Renderscript system such as
- Vector types for defining two-, three-, or four-vectors.</li></li>
- </ul>
+ Vector types for defining two-, three-, or four-vectors.</li>
</ul>
- <h3 id="reflective-api">Reflective layer APIs</h3>
+ <h3 id="reflective-api">Reflected layer APIs</h3>
- <p>These classes are not generated by the reflection process, and are actually part of the
- Android system APIs, but they are mainly used by the reflective layer classes to handle memory
- allocation and management for your Renderscript. You normally do not need to be call these classes
- directly.</p>
+ <p>These classes are mainly used by the reflected classes that are generated from your native Renderscript
+ code. They allocate and manage memory for your Renderscript on the Android system side.
+ You normally do not need to call these classes directly.</p>
<p>Because of the constraints of the Renderscript native layer, you cannot do any dynamic
memory allocation in your Renderscript <code>.rs</code> file.
@@ -193,7 +198,7 @@
The Android system object, which at this point is just an empty shell, is eventually garbage collected.
</p>
- <p>The following classes are mainly used by the reflective layer classes:</p>
+ <p>The following classes are mainly used by the reflected layer classes:</p>
<table>
<tr>
@@ -212,9 +217,9 @@
<td>
An {@link android.renderscript.Element} is the most basic element of a memory type. An
element represents one cell of a memory allocation. An element can have two forms: Basic or
- Complex. They are typically created from C structures that are used within Renderscript
- code and cannot contain pointers or nested arrays. The other common source of elements is
- bitmap formats.
+ Complex. They are typically created from C structures in your Renderscript
+ code during the reflection process. Elements cannot contain pointers or nested arrays.
+ The other common source of elements is bitmap formats.
<p>A basic element contains a single component of data of any valid Renderscript data type.
Examples of basic element data types include a single float value, a float4 vector, or a
@@ -251,12 +256,11 @@
<td>rs_allocation</td>
<td>
- An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
+ <p>An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
android.renderscript.Allocation} allocates memory based on a description of the memory that
- is represented by a {@link android.renderscript.Type}. The {@link
- android.renderscript.Type} describes an array of {@link android.renderscript.Element}s that
+ is represented by a {@link android.renderscript.Type}. The type describes an array of elements that
represent the memory to be allocated. Allocations are the primary way data moves into and
- out of scripts.
+ out of scripts.</p>
<p>Memory is user-synchronized and it's possible for allocations to exist in multiple
memory spaces concurrently. For example, if you make a call to the graphics card to load a
@@ -268,9 +272,9 @@
<p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked.
For simple arrays there are <code>copyFrom()</code> functions that take an array from the
- Android system code and copy it to the native layer memory store. Both type checked and
+ Android system and copy it to the native layer memory store. Both type checked and
unchecked copies are provided. The unchecked variants allow the Android system to copy over
- arrays of structures because it not support inherently support structures. For example, if
+ arrays of structures because it does not support structures. For example, if
there is an allocation that is an array n floats, you can copy the data contained in a
float[n] array or a byte[n*4] array.</p>
</td>
@@ -329,7 +333,7 @@
state is taken from the bind points as set in the {@link android.renderscript.RenderScriptGL}
bind methods in the control environment (VM environment).</p>
- <p>For example, you can define this at the top of your native Renderscript code:</p>
+ <p>For example, you can define this at the top of your native graphics Renderscript code:</p>
<pre>
#pragma stateVertex(parent)
#pragma stateStore(parent)
@@ -352,9 +356,9 @@
<td>rs_program_vertex</td>
<td>
- The Renderscript vertex program, also known as a vertex shader, describes the stage in the
+ <p>The Renderscript vertex program, also known as a vertex shader, describes the stage in the
graphics pipeline responsible for manipulating geometric data in a user-defined way. The
- object is constructed by providing Renderscript with the following data:
+ object is constructed by providing Renderscript with the following data:</p>
<ul>
<li>An Element describing its varying inputs or attributes</li>
@@ -365,7 +369,9 @@
inputs</li>
</ul>
- <p>Once the program is created, bind it to the graphics context. It is then used for all
+ <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
+ graphics context by calling
+ {@link android.renderscript.RenderScriptGL#bindProgramVertex bindProgramVertex()}. It is then used for all
subsequent draw calls until you bind a new program. If the program has constant inputs, the
user needs to bind an allocation containing those inputs. The allocation’s type must match
the one provided during creation. The Renderscript library then does all the necessary
@@ -389,7 +395,7 @@
<td>rs_program_fragment</td>
- <td>The Renderscript fragment program, also known as the fragment shader, is responsible for
+ <td><p>The Renderscript fragment program, also known as the fragment shader, is responsible for
manipulating pixel data in a user-defined way. It’s constructed from a GLSL shader string
containing the program body, textures inputs, and a Type object describing the constants used
by the program. Like the vertex programs, when an allocation with constant input values is
@@ -399,7 +405,7 @@
rsgAllocationSyncAll so it could send the new values to hardware. Communication between the
vertex and fragment programs is handled internally in the GLSL code. For example, if the
fragment program is expecting a varying input called varTex0, the GLSL code inside the
- program vertex must provide it.
+ program vertex must provide it.</p>
<p> To bind shader constructs to the this Program, declare a struct containing the necessary shader constants in your native Renderscript code.
This struct is generated into a reflected class that you can use as a constant input element
during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
@@ -414,7 +420,7 @@
<td>rs_program_store</td>
<td>The Renderscript ProgramStore contains a set of parameters that control how the graphics
- hardware writes to the framebuffer. It could be used to enable/disable depth writes and
+ hardware writes to the framebuffer. It could be used to enable and disable depth writes and
testing, setup various blending modes for effects like transparency and define write masks
for color components.</td>
</tr>
@@ -491,19 +497,19 @@
<ol>
<li>Analyze your application's requirements and figure out what you want to develop with
- Renderscript. To take full advantage of Renderscript, you want to use it when the computation
- or graphics performance you're getting with the normal Android system APIs is
+ Renderscript. To take full advantage of the Renderscript system, you want to use it when the computation
+ or graphics performance you're getting with the traditional framework APIs is
insufficient.</li>
<li>Design the interface of your Renderscript code and implement it using the native
Renderscript APIs that are included in the Android SDK in
- <code><sdk_root>/platforms/android-3.0/renderscript</code>.</li>
+ <code><sdk_root>/platforms/android-11/renderscript</code>.</li>
<li>Create an Android project as you would normally, in Eclipse or with the
<code>android</code> tool.</li>
<li>Place your Renderscript files in <code>src</code> folder of the Android project so that the
- build tools can generate the reflective layer classes.</li>
+ build tools can generate the reflected layer classes.</li>
<li>Create your application, calling the Renderscript through the reflected class layer when
you need to.</li>
@@ -511,16 +517,16 @@
<li>Build, install, and run your application as you would normally.</li>
</ol>
- <p>To see how a simple Renderscript application is put together, see <a href="#hello-world">The
- Hello World Renderscript Graphics Application</a>. The SDK also ships with many Renderscript
- samples in the<code><sdk_root>/samples/android-3.0/</code> directory.</p>
+ <p>To see how a simple Renderscript application is put together, see the
+ <a href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript samples</a>
+ and <a href="#hello-graphics">The Hello Graphics Application</a> section of the documentation.</p>
<h3 id="hello-graphics">The Hello Graphics Application</h3>
<p>This small application demonstrates the structure of a simple Renderscript application. You
can model your Renderscript application after the basic structure of this application. You can
find the complete source in the SDK in the
- <code><android-sdk>/platforms/android-3.0/samples/HelloWorldRS directory</code>. The
+ <code><android-sdk>/samples/android-11/HelloWorldRS directory</code>. The
application uses Renderscript to draw the string, "Hello World!" to the screen and redraws the
text whenever the user touches the screen at the location of the touch. This application is only
a demonstration and you should not use the Renderscript system to do something this trivial. The
@@ -542,7 +548,7 @@
screen.</li>
<li>
- <p>The <code><project_root>/gen</code> directory contains the reflective layer classes
+ <p>The <code><project_root>/gen</code> directory contains the reflected layer classes
that are generated by the Android build tools. You will notice a
<code>ScriptC_helloworld</code> class, which is the reflective version of the Renderscript
and contains the entry points into the <code>helloworld.rs</code> native code. This file does
@@ -550,8 +556,8 @@
</li>
</ul>
- <p>Each file has its own distinct use. The following section demonstrates in detail how the
- sample works:</p>
+ <p>Each file has its own distinct use. The following files comprise the main parts of the sample and
+ demonstrate in detail how the sample works:</p>
<dl>
<dt><code>helloworld.rs</code></dt>
@@ -626,7 +632,7 @@
<dd>This class is generated by the Android build tools and is the reflected version of the
<code>helloworld.rs</code> Renderscript. It provides a a high level entry point into the
<code>helloworld.rs</code> native code by defining the corresponding methods that you can call
- from Android system APIs.</dd>
+ from the traditional framework APIs.</dd>
<dt><code>helloworld.bc</code> bytecode</dt>
diff --git a/docs/html/guide/topics/graphics/view-animation.jd b/docs/html/guide/topics/graphics/view-animation.jd
index ad27e1c..eff6f70 100644
--- a/docs/html/guide/topics/graphics/view-animation.jd
+++ b/docs/html/guide/topics/graphics/view-animation.jd
@@ -1,4 +1,6 @@
page.title=View Animation
+parent.title=Graphics
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/manifest/uses-library-element.jd b/docs/html/guide/topics/manifest/uses-library-element.jd
index f1b5e70..1d38c1a 100644
--- a/docs/html/guide/topics/manifest/uses-library-element.jd
+++ b/docs/html/guide/topics/manifest/uses-library-element.jd
@@ -3,34 +3,101 @@
<dl class="xml">
<dt>syntax:</dt>
-<dd><pre><uses-library android:<a href="#nm">name</a>="<i>string</i>" /></pre></dd>
-
+<dd>
+<pre class="stx">
+<uses-library android:<a href="#nm">name</a>="<var>string</var>"
+ android:<a href="#rq">required</a>=["true" | "false"] />
+</pre>
+</dd>
<dt>contained in:</dt>
-<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code></dd>
-
+<dd>
+ <code>
+ <a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a>
+ </code>
+</dd>
<dt>description:</dt>
-<dd>Specifies a shared library that the application must be linked against.
-This element tells the system to include the library's code in the class
-loader for the package.
-
-<p>
-All of the {@code android} packages (such as {@link android.app},
-{@link android.content}, {@link android.view}, and {@link android.widget})
-are in the default library that all applications are automatically linked
-against. However, some packages (such as {@code maps} and {@code awt} are
-in separate libraries that are not automatically linked. Consult the
-documentation for the packages you're using to determine which library
-contains the package code.
-</p></dd>
-
+<dd>
+ Specifies a shared library that the application must be linked against.
+ This element tells the system to include the library's code in the class
+ loader for the package.
+ <p>
+ All of the {@code android} packages (such as {@link android.app},
+ {@link android.content}, {@link android.view}, and {@link android.widget})
+ are in the default library that all applications are automatically linked
+ against. However, some packages (such as {@code maps}) are
+ in separate libraries that are not automatically linked. Consult the
+ documentation for the packages you're using to determine which library
+ contains the package code.
+ </p>
+ <p>
+ This element also affects the installation of the application on a particular device and
+ the availability of the application in Android Market:
+ </p>
+ <dl>
+ <dt><em>Installation</em></dt>
+ <dd>
+ If this element is present and its {@code android:required} attribute is set to
+ {@code true}, the {@link android.content.pm.PackageManager} framework won't let the user
+ install the application unless the library is present on the user's device.
+ </dd>
+ <dt><em>Market</em></dt>
+ <dd>
+ Android Market filters applications based on the libraries installed on the
+ user's device. For more information about filtering, see the topic
+ <a href="{@docRoot}/guide/appendix/market-filters.html">Market Filters</a>.
+ </dd>
+ </dl>
+ <p>
+ The {@code android:required} attribute is described in detail in the following section.
+ </p>
+</dd>
<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt><a name="nm"></a>{@code android:name}</dt>
-<dd>The name of the library.</dd>
-</dl></dd>
-
+<dd>
+ <dl class="attr">
+ <dt><a name="nm"></a>{@code android:name}</dt>
+ <dd>
+ The name of the library. The name is provided by the
+ documentation for the package you are using. An example of this is
+ "<code>android.test.runner</code>", a package that contains Android test
+ classes.
+ </dd>
+ <dt><a name="rq"></a>{@code android:required}</dt>
+ <dd>
+ Boolean value that indicates whether the application requires the
+ library specified by {@code android:name}:
+ <ul>
+ <li>
+ <code>"true"</code>: The application does not function without this
+ library. The system will not allow the application on a device that does not
+ have the library.
+ </li>
+ <li>
+ <code>"false"</code>: The application can use the
+ library if present, but is designed to function without it if necessary.
+ The system will allow the application to be installed, even if the library is
+ not present. If you use <code>"false"</code>, you are responsible for
+ checking at runtime that the library is available.
+ <p>
+ To check for a library, you can use reflection to determine
+ if a particular class is available.
+ </p>
+ </li>
+ </ul>
+ <p>
+ The default is <code>"true"</code>.
+ </p>
+ <p>Introduced in: API Level 7.</p>
+ </dd>
+ </dl>
+</dd>
<!-- ##api level indication## -->
<dt>introduced in:</dt>
<dd>API Level 1</dd>
-</dl>
+<dt>see also:</dt>
+<dd>
+ <ul>
+ <li>{@link android.content.pm.PackageManager}</li>
+ </ul>
+</dd>
+</dl>
\ No newline at end of file
diff --git a/docs/html/guide/topics/nfc/index.jd b/docs/html/guide/topics/nfc/index.jd
index 3992099..c4917b4 100644
--- a/docs/html/guide/topics/nfc/index.jd
+++ b/docs/html/guide/topics/nfc/index.jd
@@ -31,29 +31,33 @@
</div>
</div>
- <p>Near Field Communication (NFC) is a set of short-range wireless technologies, similar to RFID.
- It typically requires a distance of 4 cm or less and operates at 13.56mhz and at rates ranging
- from 106 kbit/s to 848 kbit/s. NFC communication always involves an initiator and a target. The
- initiator actively generates an RF field that can power a passive target. This enables NFC
- targets to take very simple form factors such as tags, stickers or cards that do not require
- power. NFC peer-to-peer communication is also possible, where both devices are powered.</p>
-
- <p>Compared to other wireless technologies such as Bluetooth or WiFi, NFC provides much lower
- bandwidth and range, but provides low-cost, un-powered targets and do not require discovery or
- pairing. Users interact with NFC tags with just a tap. Targets can range in complexity. Simple
- tags just offer read and write capabilities, sometimes with one-time programmable areas to make
- the card read-only. More complex tags offer math operations, and have cryptographic hardware to
- authenticate access to a sector. The most sophisticated tags contain operating environments,
- allowing complex interactions with applets that are running on the tag.</p>
-
- <p>An Android device with NFC hardware typically acts as an initiator. This mode is also known as
- NFC reader/writer. The device actively looks for NFC tags and starts activities to handle them in
- this mode. In Android 2.3.3, devices also have some limited peer-to-peer support.</p>
+ <p>Near Field Communication (NFC) is a set of short-range wireless technologies, typically
+ requiring a distance of 4cm or less. NFC operates at 13.56mhz, and at rates ranging
+ from 106 kbit/s to 848 kbit/s. NFC communication always involves an initiator and a target.
+ The initiator actively generates an RF field that can power a passive target. This
+ enables NFC targets to take very simple form factors such as tags, stickers or cards that do
+ not require power. NFC peer-to-peer communication is also possible, where both devices
+ are powered.
+ <p>
+ Compared to other wireless technologies such as Bluetooth or WiFi, NFC provides much lower
+ bandwidth and range, but enables low-cost, un-powered targets
+ and does not require discovery or pairing. Interactions can be initiated with just a tap.
+ <p>
+ An Android device with NFC hardware will typically act as an initiator when the screen is
+ on. This mode is also known as NFC reader/writer. It will actively look for NFC tags and start
+ activities to handle them. Android 2.3.3 also has some limited P2P support.
+ <p>
+ Tags can range in complexity, simple tags just offer read/write semantics, sometimes
+ with one-time-programmable areas to make the card read-only. More complex tags offer
+ math operations, and have cryptographic hardware to authenticate access to a sector.
+ The most sophisticated tags contain operating environments, allowing
+ complex interactions with code executing on the tag.
<h2 id="api">API Overview</h2>
- <p>The {@link android.nfc} package contain the high-level classes to interact with the local
- device's NFC adapter, to represent discovered tags, and to use the NDEF data format.</p>
+ <p>The {@link android.nfc} package contains the high-level classes to interact
+ with the local device's NFC adapter, to represent discovered tags, and to use
+ the NDEF data format.
<table>
<tr>
@@ -65,44 +69,52 @@
<tr>
<td>{@link android.nfc.NfcManager}</td>
- <td>A high level manager class that enumerates the NFC adapters on this Android device. Since
- most Android devices only have one NFC adapter, you can just use the static helper {@link
- android.nfc.NfcAdapter#getDefaultAdapter()} for most situations.</td>
+
+ <td>A high level manager class that enumerates the NFC adapters on this Android device.
+ Since most Android devices only have one NFC adapter, you can just use the static helper
+ {@link android.nfc.NfcAdapter#getDefaultAdapter(Context)} for most situations.</td>
</tr>
<tr>
<td>{@link android.nfc.NfcAdapter}</td>
- <td>Represents the local NFC adapter and defines the Intents that are used in the tag
- dispatch system. It provides methods to register for foreground tag dispatching and
- foreground NDEF pushing. Foreground NDEF push is the only peer-to-peer support that is
- currently provided in Android.</td>
+ <td>Represents the local NFC adapter. Defines the intent's used to request
+ tag dispatch to your activity, and provides methods to register for foreground
+ tag dispatch and foreground NDEF push. Foreground NDEF push is the only
+ peer-to-peer support that is currently provided in Android.</td>
</tr>
<tr>
<td>{@link android.nfc.NdefMessage} and {@link android.nfc.NdefRecord}</td>
- <td>NDEF is an NFC Forum defined data structure, designed to efficiently store data on NFC
- tags, such as Text, URLs, and other MIME types. An {@link android.nfc.NdefMessage} acts as a
+ <td>NDEF is an NFC Forum defined data structure, designed to efficiently
+ store data on NFC tags, such as text, URL's, and other MIME types. A
+ {@link android.nfc.NdefMessage} acts as a
container for the data that you want to transmit or read. One {@link android.nfc.NdefMessage}
- object contains zero or more {@link android.nfc.NdefRecord}s. Each NDEF Record has a type
- such as Text, URL, Smart Poster, or any MIME type. The type of the first NDEF Record in the
- NDEF message is used to dispatch a tag to an Activity.</td>
+ object contains zero or more {@link android.nfc.NdefRecord}s. Each NDEF record
+ has a type such as text, URL, smart poster, or any MIME data. The type of the
+ first NDEF record in the NDEF message is used to dispatch a tag to an activity
+ on Android.</td>
</tr>
<tr>
<td>{@link android.nfc.Tag}</td>
- <td>Represents a passive NFC target. These can come in many form factors such as a tag, card,
- FOB, or an even more complex device doing card emulation. When a tag is discovered, a {@link
- android.nfc.Tag} object is created and wrapped inside an Intent. The dispatch system sends
- the Intent to a compatible Activity <code>startActivity()</code>. You can use the {@link
+ <td>Represents a passive NFC target. These can come in many form factors such as
+ a tag, card, key fob, or even a phone doing card emulation. When a tag is
+ discovered, a {@link android.nfc.Tag} object is created and wrapped inside an
+ Intent. The NFC dispatch system sends the intent to a compatible actvitiy
+ using <code>startActivity()</code>. You can use the {@link
android.nfc.Tag#getTechList getTechList()} method to determine the technologies supported by
this tag and create the corresponding {@link android.nfc.tech.TagTechnology} object with one
of classes provided by {@link android.nfc.tech}.</td>
</tr>
</table>
+ <p>The {@link android.nfc.tech} package contains classes to query properties
+ and perform I/O operations on a tag. The classes are divided to represent different
+ NFC technologies that can be available on a tag.
+
<p>The {@link android.nfc.tech} package contains classes to query properties and perform I/O
operations on a tag. The classes are divided to represent different NFC technologies that can be
available on a Tag:</p>
@@ -117,7 +129,7 @@
<tr>
<td>{@link android.nfc.tech.TagTechnology}</td>
- <td>The interface that all Tag Technology classes must implement.</td>
+ <td>The interface that all tag technology classes must implement.</td>
</tr>
<tr>
@@ -153,8 +165,8 @@
<tr>
<td>{@link android.nfc.tech.Ndef}</td>
- <td>Provides access to NDEF data and operations on NFC Tags that have been formatted as
- NDEF.</td>
+ <td>Provides access to NDEF data and operations on NFC tags that have been formatted as NDEF.
+ </td>
</tr>
<tr>
@@ -166,15 +178,15 @@
<tr>
<td>{@link android.nfc.tech.MifareClassic}</td>
- <td>Provides access to MIFARE Classic properties and I/O operations. Not all Android devices
- provide implementations for this class.</td>
+ <td>Provides access to MIFARE Classic properties and I/O operations, if this
+ Android device supports MIFARE.</td>
</tr>
<tr>
<td>{@link android.nfc.tech.MifareUltralight}</td>
- <td>Provides access to MIFARE Ultralight properties and I/O operations. Not all Android
- devices provide implementations for this class.</td>
+ <td>Provides access to MIFARE Ultralight properties and I/O operations, if this
+ Android device supports MIFARE.</td>
</tr>
</table>
@@ -191,12 +203,13 @@
</li>
<li>The minimum SDK version that your application can support. API level 9 only supports
- limited tag dispatching with {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}, and only
- gives access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES} extra.
- No other tag properties or I/O operations are accessible. API level 10 adds comprehensive
- reader/writer support, so you probably want to use this for more functionality.
- <pre class="pretty-print">
-<uses-sdk android:minSdkVersion="9|10"/>
+ limited tag dispatch via {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED},
+ and only gives access to NDEF messages via the {@link android.nfc.NfcAdapter#EXTRA_NDEF_MESSAGES}
+ extra. No other tag properties or I/O operations are accessible. You probably want
+ to use API level 10 which includes comprehensive reader/writer support.
+
+<pre class="pretty-print">
+<uses-sdk android:minSdkVersion="10"/>
</pre>
</li>
diff --git a/docs/html/guide/topics/testing/activity_testing.jd b/docs/html/guide/topics/testing/activity_testing.jd
index 6392ad7..51121f4 100644
--- a/docs/html/guide/topics/testing/activity_testing.jd
+++ b/docs/html/guide/topics/testing/activity_testing.jd
@@ -1,4 +1,6 @@
page.title=Activity Testing
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/testing/contentprovider_testing.jd b/docs/html/guide/topics/testing/contentprovider_testing.jd
index e42e631..edaae8c 100644
--- a/docs/html/guide/topics/testing/contentprovider_testing.jd
+++ b/docs/html/guide/topics/testing/contentprovider_testing.jd
@@ -1,4 +1,6 @@
page.title=Content Provider Testing
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/testing/service_testing.jd b/docs/html/guide/topics/testing/service_testing.jd
index 77884779..eae8607 100644
--- a/docs/html/guide/topics/testing/service_testing.jd
+++ b/docs/html/guide/topics/testing/service_testing.jd
@@ -1,4 +1,6 @@
page.title=Service Testing
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/guide/topics/testing/testing_android.jd b/docs/html/guide/topics/testing/testing_android.jd
index 6f3048c..c8a3f6e 100755
--- a/docs/html/guide/topics/testing/testing_android.jd
+++ b/docs/html/guide/topics/testing/testing_android.jd
@@ -1,4 +1,6 @@
page.title=Testing Fundamentals
+parent.title=Testing
+parent.link=index.html
@jd:body
<div id="qv-wrapper">
@@ -653,10 +655,12 @@
It guides you through a more complex testing scenario that you develop against a
more realistic application.
</li>
+ <!-- sample is not available
<li>
- The sample test package <a href="{@docRoot}resources/samples/AlarmServiceTest"}>
+ The sample test package <a href="{@docRoot}resources/samples/AlarmServiceTest/index.html">
Alarm Service Test</a> is an example of testing a {@link android.app.Service}. It contains
a set of unit tests for the Alarm Service sample application's {@link android.app.Service}.
</li>
+ -->
</ul>
diff --git a/docs/html/guide/topics/testing/what_to_test.jd b/docs/html/guide/topics/testing/what_to_test.jd
index e8a27da..99061df 100644
--- a/docs/html/guide/topics/testing/what_to_test.jd
+++ b/docs/html/guide/topics/testing/what_to_test.jd
@@ -1,4 +1,6 @@
page.title=What To Test
+parent.title=Testing
+parent.link=index.html
@jd:body
<p>
As you develop Android applications, knowing what to test is as important as knowing how to
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index b8d1928..065f95a 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -38,7 +38,15 @@
<li>{@link android.app.ActionBar}</li>
<li>{@link android.view.Menu}</li>
</ol>
-
+
+ <h2>Related samples</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#ActionBar">API
+ Demos</a></li>
+ <li><a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a></li>
+ </ol>
+
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a></li>
@@ -363,7 +371,7 @@
in the overflow menu as a normal menu item and you must respond to it from the {@link
android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method. (For a
guide to providing search functionality, see the <a
-href="{@docRoot}gudie/topics/search/index.html">Search</a> documentation.)</p>
+href="{@docRoot}guide/topics/search/index.html">Search</a> documentation.)</p>
<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}.
@@ -397,7 +405,7 @@
<img src="{@docRoot}images/ui/actionbar-tabs.png" alt="" />
<p class="img-caption"><strong>Figure 6.</strong> Screenshot of tabs in the
Action Bar, from the <a
-href="{@docRoot}resources/samples/Honeycomb-Gallery/index.html">Honeycomb Gallery</a> sample
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> sample
application.</p>
</div>
diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd
index 46ccdf8..c33c507 100644
--- a/docs/html/guide/topics/ui/drag-drop.jd
+++ b/docs/html/guide/topics/ui/drag-drop.jd
@@ -289,14 +289,14 @@
<p>
To get the action type, a listener calls {@link android.view.DragEvent#getAction()}. There
are six possible values, defined by constants in the {@link android.view.DragEvent} class. These
- are listed in <a href="table1">table 1</a>.
+ are listed in <a href="#table1">table 1</a>.
</p>
<p>
The {@link android.view.DragEvent} object also contains the data that your application provided
to the system in the call to
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
Some of the data is valid only for certain action types. The data that is valid for each action
- type is summarized in <a href="table2">table 2</a>. It is also described in detail with
+ type is summarized in <a href="#table2">table 2</a>. It is also described in detail with
the event for which it is valid in the section
<a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
</p>
diff --git a/docs/html/images/developing/hv_device_window.png b/docs/html/images/developing/hv_device_window.png
new file mode 100644
index 0000000..2bb80a8
--- /dev/null
+++ b/docs/html/images/developing/hv_device_window.png
Binary files differ
diff --git a/docs/html/images/developing/hv_pixelperfect.png b/docs/html/images/developing/hv_pixelperfect.png
new file mode 100644
index 0000000..6d19119
--- /dev/null
+++ b/docs/html/images/developing/hv_pixelperfect.png
Binary files differ
diff --git a/docs/html/images/developing/hv_treeview_screenshot.png b/docs/html/images/developing/hv_treeview_screenshot.png
new file mode 100644
index 0000000..c0e7ac5
--- /dev/null
+++ b/docs/html/images/developing/hv_treeview_screenshot.png
Binary files differ
diff --git a/docs/html/images/developing/hv_view_hierarchy_window.png b/docs/html/images/developing/hv_view_hierarchy_window.png
new file mode 100644
index 0000000..0d8b263
--- /dev/null
+++ b/docs/html/images/developing/hv_view_hierarchy_window.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 0c57527..2248752 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -129,16 +129,17 @@
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"Android 2.3.3",
- 'img':"gingerdroid.png",
- 'title':"Android 2.3.3, more NFC!",
- 'desc': "<p>Android 2.3.3 is now available for the Android SDK. "
-+ "This update adds new NFC capabilities for developers, including advanced tag dispatching APIs "
-+ "and the ability to write to tags.</p>"
-+ "<p>The new APIs enable exciting new applications, such as for ticketing, "
-+ "ratings, check-ins, advertising, and data exchange with other devices. "
-+ "For more information about Android 2.3.3, read the "
-+ "<a href='/sdk/android-2.3.3.html'>version notes</a>.</p>"
+ 'name':"Android 3.0",
+ 'img':"honeycomb-android.png",
+ 'title':"Android 3.0 is here!",
+ 'desc': "<p>Android 3.0 is now available for the Android SDK. It offers a redesigned UI and "
++ "all new developer APIs for an optimized experience on tablets and similar devices. "
++ "For more information about what's in Android 3.0, read the "
++ "<a href='{@docRoot}sdk/android-3.0.html'>version notes</a>.</p>"
++ "<p>If you have an existing SDK, add Android 3.0 as an "
++ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
++ "component</a>. If you're new to Android, install the "
++ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
},
'tv': {
diff --git a/docs/html/resources/articles/avoiding-memory-leaks.jd b/docs/html/resources/articles/avoiding-memory-leaks.jd
index 3361bc1..395f590 100644
--- a/docs/html/resources/articles/avoiding-memory-leaks.jd
+++ b/docs/html/resources/articles/avoiding-memory-leaks.jd
@@ -1,4 +1,6 @@
page.title=Avoiding Memory Leaks
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/backward-compatibility.jd b/docs/html/resources/articles/backward-compatibility.jd
index ad64dfc..f96d587 100644
--- a/docs/html/resources/articles/backward-compatibility.jd
+++ b/docs/html/resources/articles/backward-compatibility.jd
@@ -1,4 +1,6 @@
page.title=Backward Compatibility for Applications
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/can-i-use-this-intent.jd b/docs/html/resources/articles/can-i-use-this-intent.jd
index a726189..c527331 100644
--- a/docs/html/resources/articles/can-i-use-this-intent.jd
+++ b/docs/html/resources/articles/can-i-use-this-intent.jd
@@ -1,4 +1,6 @@
page.title=Can I Use this Intent?
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android offers a very powerful and yet easy-to-use message type called
diff --git a/docs/html/resources/articles/contacts.jd b/docs/html/resources/articles/contacts.jd
index c837dc3..8365d29 100644
--- a/docs/html/resources/articles/contacts.jd
+++ b/docs/html/resources/articles/contacts.jd
@@ -1,4 +1,6 @@
page.title=Using the Contacts API
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Starting from Android 2.0 (API Level 5), the Android platform provides an
diff --git a/docs/html/resources/articles/creating-input-method.jd b/docs/html/resources/articles/creating-input-method.jd
index 6f932df..e4b77f4 100644
--- a/docs/html/resources/articles/creating-input-method.jd
+++ b/docs/html/resources/articles/creating-input-method.jd
@@ -1,4 +1,6 @@
page.title=Creating an Input Method
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/drawable-mutations.jd b/docs/html/resources/articles/drawable-mutations.jd
index f979829..c5818fc 100644
--- a/docs/html/resources/articles/drawable-mutations.jd
+++ b/docs/html/resources/articles/drawable-mutations.jd
@@ -1,4 +1,6 @@
page.title=Drawable Mutations
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android's drawables are extremely useful to easily build applications. A
diff --git a/docs/html/resources/articles/faster-screen-orientation-change.jd b/docs/html/resources/articles/faster-screen-orientation-change.jd
index f82e592..52531bb 100644
--- a/docs/html/resources/articles/faster-screen-orientation-change.jd
+++ b/docs/html/resources/articles/faster-screen-orientation-change.jd
@@ -1,4 +1,6 @@
page.title=Faster Screen Orientation Change
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/future-proofing.jd b/docs/html/resources/articles/future-proofing.jd
index ee98186..b8aeedf 100644
--- a/docs/html/resources/articles/future-proofing.jd
+++ b/docs/html/resources/articles/future-proofing.jd
@@ -1,4 +1,6 @@
page.title=Future-Proofing Your Apps
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>It's important to implement your application so that it will not break as new
diff --git a/docs/html/resources/articles/gestures.jd b/docs/html/resources/articles/gestures.jd
index 8711645b..5b8d760 100644
--- a/docs/html/resources/articles/gestures.jd
+++ b/docs/html/resources/articles/gestures.jd
@@ -1,4 +1,6 @@
page.title=Gestures
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Touch screens are a great way to interact with applications on
diff --git a/docs/html/resources/articles/glsurfaceview.jd b/docs/html/resources/articles/glsurfaceview.jd
index 57403ea..45407a9 100644
--- a/docs/html/resources/articles/glsurfaceview.jd
+++ b/docs/html/resources/articles/glsurfaceview.jd
@@ -1,4 +1,6 @@
page.title=Introducing GLSurfaceView
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/index.jd b/docs/html/resources/articles/index.jd
index d2b7645..220a4ed 100644
--- a/docs/html/resources/articles/index.jd
+++ b/docs/html/resources/articles/index.jd
@@ -1,4 +1,6 @@
page.title=Technical Articles
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<dl>
diff --git a/docs/html/resources/articles/layout-tricks-efficiency.jd b/docs/html/resources/articles/layout-tricks-efficiency.jd
index b7b5761..00b4147 100644
--- a/docs/html/resources/articles/layout-tricks-efficiency.jd
+++ b/docs/html/resources/articles/layout-tricks-efficiency.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Creating Efficient Layouts
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android UI toolkit offers several layout managers that are
diff --git a/docs/html/resources/articles/layout-tricks-merge.jd b/docs/html/resources/articles/layout-tricks-merge.jd
index 95409e4..0ca0317 100644
--- a/docs/html/resources/articles/layout-tricks-merge.jd
+++ b/docs/html/resources/articles/layout-tricks-merge.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Merging Layouts
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The articles showed you how to use the <code><include /></code> tag in XML layouts, to
diff --git a/docs/html/resources/articles/layout-tricks-reuse.jd b/docs/html/resources/articles/layout-tricks-reuse.jd
index 396e2127..179c1d8 100644
--- a/docs/html/resources/articles/layout-tricks-reuse.jd
+++ b/docs/html/resources/articles/layout-tricks-reuse.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Creating Reusable UI Components
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android platform offers a wide variety of UI <em>widgets</em>, small
diff --git a/docs/html/resources/articles/layout-tricks-stubs.jd b/docs/html/resources/articles/layout-tricks-stubs.jd
index 88bcb78..64f07f9 100644
--- a/docs/html/resources/articles/layout-tricks-stubs.jd
+++ b/docs/html/resources/articles/layout-tricks-stubs.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Using ViewStubs
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Sharing and reusing UI components is very easy with Android, thanks to the <a
diff --git a/docs/html/resources/articles/listview-backgrounds.jd b/docs/html/resources/articles/listview-backgrounds.jd
index f4c6998..c4037ba 100644
--- a/docs/html/resources/articles/listview-backgrounds.jd
+++ b/docs/html/resources/articles/listview-backgrounds.jd
@@ -1,4 +1,6 @@
page.title=ListView Backgrounds: An Optimization
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>{@link android.widget.ListView} is one of Android's most widely used widgets.
diff --git a/docs/html/resources/articles/live-folders.jd b/docs/html/resources/articles/live-folders.jd
index be974f4..aeab997 100644
--- a/docs/html/resources/articles/live-folders.jd
+++ b/docs/html/resources/articles/live-folders.jd
@@ -1,4 +1,6 @@
page.title=Live Folders
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Live folders, introduced in Android 1.5 (API Level 3), let you display any source of data
diff --git a/docs/html/resources/articles/live-wallpapers.jd b/docs/html/resources/articles/live-wallpapers.jd
index ea67fed..bfbbb34 100644
--- a/docs/html/resources/articles/live-wallpapers.jd
+++ b/docs/html/resources/articles/live-wallpapers.jd
@@ -1,4 +1,6 @@
page.title=Live Wallpapers
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
@@ -27,35 +29,36 @@
<img src="images/live_wallpapers_small.png" style="align:center" />
<p>Creating your own live wallpaper is easy, especially if you have had
-previous experience with <a
-href="../../../reference/android/view/SurfaceView.html"><code>SurfaceView</code></a> or <a
-href="../../../reference/android/graphics/Canvas.html"><code>Canvas</code></a>.
+previous experience with {@link android.view.SurfaceView} or {@link
+android.graphics.Canvas}.
To learn how to create a live wallpaper, you should check out the <a
href="../samples/CubeLiveWallpaper/index.html">CubeLiveWallpaper sample code</a>.</p>
-<p>In terms of implementation, a live wallpaper is very similar to a regular
-Android <a href="../../../reference/android/app/Service.html">service</a>. The
-only difference is the addition of a new method, <a
-href="../../../reference/android/service/wallpaper/WallpaperService.html#onCreateEngine()">{@code
-onCreateEngine()}</a>, whose goal is to create a <a
-href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html">
-<code>WallpaperService.Engine</code></a>. The engine is responsible for
+<p>In terms of implementation, a live wallpaper is very similar to a {@link android.app.Service}.
+The only difference is the addition of a new method, {@link
+android.service.wallpaper.WallpaperService#onCreateEngine()}, whose goal is to create a {@link
+android.service.wallpaper.WallpaperService.Engine}. The engine is responsible for
handling the lifecycle and drawing of a wallpaper. The system provides a surface
-on which you can draw, just like you would with a <code>SurfaceView</code></a>.
+on which you can draw, just like you would with a {@link android.view.SurfaceView}.
Drawing a wallpaper can be very expensive so you should optimize your code
as much as possible to avoid using too much CPU, not only for battery life
but also to avoid slowing down the rest of the system. That is also why the
-most important part of the lifecycle of a wallpaper is <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onVisibilityChanged%28boolean%29">when it becomes invisible</a>.
+most important part of the lifecycle of a wallpaper is when it becomes visible, as indicated
+by a call to {@link android.service.wallpaper.WallpaperService.Engine#onVisibilityChanged
+onVisibilityChanged()}.
When invisible, such as when the user launches an application that covers
the home screen, a wallpaper must stop all activity.</p>
<p>The engine can also implement several methods to interact with the user
or the home application. For instance, if you want your wallpaper to scroll
-along when the user swipes from one home screen to another, you can use <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onOffsetsChanged%28float,%20float,%20float,%20float,%20int,%20int%29"><code>onOffsetsChanged()</code></a>.
-To react to touch events, simply implement <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onTouchEvent%28android.view.MotionEvent%29"><code>onTouchEvent(MotionEvent)</code></a>.
+along when the user swipes from one home screen to another, you can use
+{@link android.service.wallpaper.WallpaperService.Engine#onOffsetsChanged
+onOffsetsChanged()}.
+To react to touch events, simply implement {@link
+android.service.wallpaper.WallpaperService.Engine#onTouchEvent onTouchEvent()}.
Finally, applications can send arbitrary commands to the live wallpaper.
-Currently, only the standard home application sends commands to the <a
-href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onCommand%28java.lang.String,%20int,%20int,%20int,%20android.os.Bundle,%20boolean%29"><code>onCommand()</code></a>
+Currently, only the standard home application sends commands to the
+{@link android.service.wallpaper.WallpaperService.Engine#onCommand onCommand()}
method of the live wallpaper:</p>
<ul>
@@ -78,9 +81,9 @@
<ul>
<li><code><uses-sdk android:minSdkVersion="7" /></code>, which indicates
to Android Market and the platform that your application requires Android 2.1 or
-higher. For more information, see the <a href="../../../guide/appendix/api-levels.html">API
+higher. For more information, see the <a href="{@docRoot}guide/appendix/api-levels.html">API
Levels</a> and the documentation for the
-<a href="../../../guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html"><code><uses-sdk></code></a>
element.</li>
<li><code><uses-feature android:name="android.software.live_wallpaper" /></code>,
which tells Android Market that your application includes a live wallpaper
@@ -89,7 +92,9 @@
displays your application only to users whose devices support live wallpapers,
while hiding it from other devices on which it would not be able to run. For
more information, see the documentation for the
-<a href="../../../guide/topics/manifest/uses-feature-element.html"><code><uses-feature></code></a>
+<a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code
+<uses-feature></a>
element.</li>
</ul>
diff --git a/docs/html/resources/articles/on-screen-inputs.jd b/docs/html/resources/articles/on-screen-inputs.jd
index 30b4c84..6a028c8 100644
--- a/docs/html/resources/articles/on-screen-inputs.jd
+++ b/docs/html/resources/articles/on-screen-inputs.jd
@@ -1,4 +1,6 @@
page.title=Onscreen Input Methods
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/painless-threading.jd b/docs/html/resources/articles/painless-threading.jd
index 17cec35..fea7ee2 100644
--- a/docs/html/resources/articles/painless-threading.jd
+++ b/docs/html/resources/articles/painless-threading.jd
@@ -1,4 +1,6 @@
page.title=Painless Threading
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>This article discusses the threading model used by Android applications and how applications can ensure best UI performance by spawning worker threads to handle long-running operations, rather than handling them in the main thread. The article also explains the API that your application can use to interact with Android UI toolkit components running on the main thread and spawn managed worker threads. </p>
diff --git a/docs/html/resources/articles/qsb.jd b/docs/html/resources/articles/qsb.jd
index d47ba54..01fb115 100644
--- a/docs/html/resources/articles/qsb.jd
+++ b/docs/html/resources/articles/qsb.jd
@@ -1,4 +1,6 @@
page.title=Quick Search Box
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/speech-input.jd b/docs/html/resources/articles/speech-input.jd
index 282b619..d42bd59 100644
--- a/docs/html/resources/articles/speech-input.jd
+++ b/docs/html/resources/articles/speech-input.jd
@@ -1,4 +1,6 @@
page.title=Speech Input
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p> People love their mobile phones because they can stay in touch wherever they
diff --git a/docs/html/resources/articles/timed-ui-updates.jd b/docs/html/resources/articles/timed-ui-updates.jd
index 863387c..7a0804f 100644
--- a/docs/html/resources/articles/timed-ui-updates.jd
+++ b/docs/html/resources/articles/timed-ui-updates.jd
@@ -1,4 +1,6 @@
page.title=Updating the UI from a Timer
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<img style="margin: 1.5em; float: right;" src="images/JFlubber.png" alt="" id="BLOGGER_PHOTO_ID_5135098660116808706" border="0">
diff --git a/docs/html/resources/articles/touch-mode.jd b/docs/html/resources/articles/touch-mode.jd
index e340062..5eae9b9 100644
--- a/docs/html/resources/articles/touch-mode.jd
+++ b/docs/html/resources/articles/touch-mode.jd
@@ -1,4 +1,6 @@
page.title=Touch Mode
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>This article explains the <em>touch mode</em>, one of the most
diff --git a/docs/html/resources/articles/track-mem.jd b/docs/html/resources/articles/track-mem.jd
index d580e82..c4184b5 100644
--- a/docs/html/resources/articles/track-mem.jd
+++ b/docs/html/resources/articles/track-mem.jd
@@ -1,4 +1,6 @@
page.title=Tracking Memory Allocations
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Writing efficient mobile applications is not always straightforward. In
diff --git a/docs/html/resources/articles/tts.jd b/docs/html/resources/articles/tts.jd
index e3fad91..7d07a89 100644
--- a/docs/html/resources/articles/tts.jd
+++ b/docs/html/resources/articles/tts.jd
@@ -1,4 +1,6 @@
page.title=Using Text-to-Speech
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Starting with Android 1.6 (API Level 4), the Android platform includes a new
diff --git a/docs/html/resources/articles/ui-1.5.jd b/docs/html/resources/articles/ui-1.5.jd
index c10cf52..2edaa2e 100644
--- a/docs/html/resources/articles/ui-1.5.jd
+++ b/docs/html/resources/articles/ui-1.5.jd
@@ -1,4 +1,6 @@
page.title=UI Framework Changes in Android 1.5
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/ui-1.6.jd b/docs/html/resources/articles/ui-1.6.jd
index 10cb524..09108dd 100644
--- a/docs/html/resources/articles/ui-1.6.jd
+++ b/docs/html/resources/articles/ui-1.6.jd
@@ -1,4 +1,6 @@
page.title=UI Framework Changes in Android 1.6
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android 1.6 introduces numerous enhancements and bug fixes in the UI
diff --git a/docs/html/resources/articles/using-webviews.jd b/docs/html/resources/articles/using-webviews.jd
index 3a1f34c..3a2430b 100644
--- a/docs/html/resources/articles/using-webviews.jd
+++ b/docs/html/resources/articles/using-webviews.jd
@@ -1,4 +1,6 @@
page.title=Using WebViews
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>A small application called <a title="WebViewDemo"
diff --git a/docs/html/resources/articles/wikinotes-intents.jd b/docs/html/resources/articles/wikinotes-intents.jd
index bc64544..78fe62e 100644
--- a/docs/html/resources/articles/wikinotes-intents.jd
+++ b/docs/html/resources/articles/wikinotes-intents.jd
@@ -1,4 +1,6 @@
page.title=WikiNotes: Routing Intents
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/wikinotes-linkify.jd b/docs/html/resources/articles/wikinotes-linkify.jd
index 21b1f13..fb49f86 100644
--- a/docs/html/resources/articles/wikinotes-linkify.jd
+++ b/docs/html/resources/articles/wikinotes-linkify.jd
@@ -1,4 +1,6 @@
page.title=WikiNotes: Linkify your Text!
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<img style="margin-left: 1.5em; margin-bottom:1.5em; float: right;"
diff --git a/docs/html/resources/articles/window-bg-speed.jd b/docs/html/resources/articles/window-bg-speed.jd
index bd7a303..c5e5e90 100644
--- a/docs/html/resources/articles/window-bg-speed.jd
+++ b/docs/html/resources/articles/window-bg-speed.jd
@@ -1,4 +1,6 @@
page.title=Window Backgrounds & UI Speed
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Some Android applications require to squeeze every bit of performance out of
diff --git a/docs/html/resources/articles/zipalign.jd b/docs/html/resources/articles/zipalign.jd
index 013d0fe..9e767aa 100644
--- a/docs/html/resources/articles/zipalign.jd
+++ b/docs/html/resources/articles/zipalign.jd
@@ -1,4 +1,6 @@
page.title=Zipalign: an Easy Optimization
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android SDK includes a tool called <a
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index febdb9a..b80e59a 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -496,6 +496,16 @@
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/Renderscript/index.html',
+ title: {
+ en: 'Renderscript'
+ },
+ description: {
+ en: 'A set of samples that demonstrate how to use various features of the Renderscript APIs.'
+ }
+ },
+ {
tags: ['sample', 'accountsync'],
path: 'samples/SampleSyncAdapter/index.html',
title: {
@@ -569,7 +579,7 @@
tags: ['sample', 'new', 'newfeature', 'widgets'],
path: 'samples/StackWidget/index.html',
title: {
- en: 'StackView App Widget'
+ en: 'StackView Widget'
},
description: {
en: 'Demonstrates how to create a simple collection widget containing a StackView.'
@@ -619,7 +629,7 @@
tags: ['sample', 'widgets', 'newfeature', 'new'],
path: 'samples/WeatherListWidget/index.html',
title: {
- en: 'Weather List Widget Sample'
+ en: 'Weather List Widget'
},
description: {
en: 'A more complex collection-widget example which uses a ContentProvider as its data source.'
diff --git a/docs/html/resources/samples/get.jd b/docs/html/resources/samples/get.jd
index 1b6d137..86ec836 100644
--- a/docs/html/resources/samples/get.jd
+++ b/docs/html/resources/samples/get.jd
@@ -1,4 +1,6 @@
page.title=Getting the Samples
+parent.title=Sample Code
+parent.link=../browser.html?tag=sample
@jd:body
diff --git a/docs/html/resources/tutorials/hello-world.jd b/docs/html/resources/tutorials/hello-world.jd
index 67c2521..020c738 100644
--- a/docs/html/resources/tutorials/hello-world.jd
+++ b/docs/html/resources/tutorials/hello-world.jd
@@ -1,4 +1,6 @@
page.title=Hello, World
+parent.title=Tutorials
+parent.link=../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/localization/index.jd b/docs/html/resources/tutorials/localization/index.jd
index 8a60814..de4433b 100755
--- a/docs/html/resources/tutorials/localization/index.jd
+++ b/docs/html/resources/tutorials/localization/index.jd
@@ -1,4 +1,6 @@
page.title=Hello, L10N
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/resources/tutorials/notepad/index.jd b/docs/html/resources/tutorials/notepad/index.jd
index f569314..dd92184 100644
--- a/docs/html/resources/tutorials/notepad/index.jd
+++ b/docs/html/resources/tutorials/notepad/index.jd
@@ -1,4 +1,6 @@
page.title=Notepad Tutorial
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
diff --git a/docs/html/resources/tutorials/testing/activity_test.jd b/docs/html/resources/tutorials/testing/activity_test.jd
index c94e8ab..4b861e2 100644
--- a/docs/html/resources/tutorials/testing/activity_test.jd
+++ b/docs/html/resources/tutorials/testing/activity_test.jd
@@ -1,4 +1,6 @@
page.title=Activity Testing
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/testing/helloandroid_test.jd b/docs/html/resources/tutorials/testing/helloandroid_test.jd
index b47c334..4d949c8 100644
--- a/docs/html/resources/tutorials/testing/helloandroid_test.jd
+++ b/docs/html/resources/tutorials/testing/helloandroid_test.jd
@@ -1,4 +1,6 @@
page.title=Hello, Testing
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/views/index.jd b/docs/html/resources/tutorials/views/index.jd
index 6ea7683..bba83307 100644
--- a/docs/html/resources/tutorials/views/index.jd
+++ b/docs/html/resources/tutorials/views/index.jd
@@ -1,4 +1,6 @@
page.title=Hello, Views
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<style>
diff --git a/docs/html/sdk/android-3.0-optimize.jd b/docs/html/sdk/android-3.0-optimize.jd
new file mode 100644
index 0000000..a22e69a
--- /dev/null
+++ b/docs/html/sdk/android-3.0-optimize.jd
@@ -0,0 +1,397 @@
+page.title=Optimizing Apps for Android 3.0
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>In this document</h2>
+<ol>
+<li><a href="#Setup">Set Up Your SDK with Android 3.0</a></li>
+<li><a href="#SearchableConfiguration">Optimize Your App for Tablets and Similar Devices</a></li>
+<li><a href="#SearchableActivity">Upgrade or Develop a New App for Tablets and Similar
+Devices</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>If you're developing an Android application, Android 3.0 introduces several features that allow
+you to enhance your user's experience on tablets and similar devices. Any application you've already
+published is compatible with devices running Android 3.0, by default, because Android applications
+are forward-compatible. However, there are some simple changes you should make to optimize your
+application for tablet-type devices.</p>
+
+<p>This document shows how you can optimize your existing application for Android 3.0 and
+maintain compatibility with older versions or upgrade your application completely with new APIs.</p>
+
+
+<p><b>To get started:</b></p>
+
+<ol>
+ <li><a href="#Setup">Set up your SDK with Android 3.0</a>.</li>
+ <li>Then choose to either optimize or upgrade:
+ <ol type="a">
+ <li><a href="#Optimize">Optimize Your App for Tablets and Similar Devices</a>.
+ <p>When you have an existing application and want to maintain compatibility with
+older versions of Android.</p>
+ </li>
+ <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</a>.
+ <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
+ create a new application targeted to tablets and similar devices.</p></li>
+ </ol>
+ </li>
+</ol>
+
+
+<h2 id="Setup">Set Up Your SDK with Android 3.0</h2>
+
+<p>To start testing and developing your application on Android 3.0, set up your existing Android
+SDK with the new platform:</p>
+
+<p>(If you don't have an existing Android SDK, <a href="{@docRoot}sdk/index.html">download the
+SDK starter package now</a>.)</p>
+
+<ol>
+ <li><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
+Manager</a> and install the following:
+ <ul>
+ <li>SDK Platform Android 3.0</li>
+ <li>Android SDK Tools, revision 10</li>
+ <li>Android SDK Platform-tools, revision 3</li>
+ <li>Documentation for Android SDK, API 11</li>
+ <li>Samples for SDK API 11</li>
+ </ul>
+ </li>
+ <li><a href="{@docRoot}guide/developing/other-ide.html#AVD">Create an AVD</a> for a tablet-type
+device:
+ <p>Set the target to "Android 3.0" and the skin to "WXGA" (the default skin).</p></li>
+</ol>
+
+
+<h3>About emulator performance</h3>
+
+<p>Because the Android emulator must simulate the ARM instruction set on your computer
+and the WXGA screen is significantly larger than a typical virtual device, emulator performance is
+much slower than a real device.</p>
+
+<p>In particular, initializing the emulator can be slow and can take several minutes, depending on
+your hardware. When the emulator is booting, there is limited user feedback, so please be patient
+and wait until you see the home screen (or lock screen) appear. </p>
+
+<p>However, you don't need to boot the emulator each time you rebuild your
+application—typically you only need to boot at the start of a session and keep it running.
+Also see the tip below for information about using a snapshot to drastically reduce startup time
+after the first initialization. </p>
+
+<p>We're working hard to resolve the performance issues and it will improve in future tools
+releases. For the time being, the emulator is still best way to evaluate your application's
+appearance and functionality on Android 3.0 without a real device.</p>
+
+<p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable snapshots
+for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in the AVD creator
+to <strong>Enable</strong> snapshots). Then, start the AVD from the AVD manager and check <b>Launch
+from snapshot</b> and <b>Save to snapshot</b>. This way, when you close the emulator, a snapshot of
+the AVD state is saved and used to quickly relaunch the AVD next time. However, when you choose to
+save a snapshot, the emulator will be slow to close, so you might want to disable <b>Save to
+snapshot</b> after you've acquired an initial snapshot (after you close the AVD for the first
+time).</p>
+
+
+
+<h2 id="Optimize">Optimize Your Application for Tablets and Similar Devices</h2>
+
+<p>If you've already developed an application for an earlier version of Android, there are a few
+things you can do to optimize it for a tablet-style experience on Android 3.0 without changing the
+minimum version required (you don't need to change your manifest's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a>).</p>
+
+<p class="note"><strong>Note:</strong> All Android applications are forward-compatible, so
+there's nothing you <em>have to</em> do—if your application is a good citizen of the Android
+APIs, your app should work fine on devices running Android 3.0. However, in order to provide users
+a better experience when using your app on an Android 3.0 tablet or similar-size device, you
+should update your application to inherit the new system theme and provide some optimizations for
+larger screens.</p>
+
+<p>Here are a few things you can do to optimize your application for devices running Android
+3.0:</p>
+
+<ol>
+ <li><b>Test your current application on Android 3.0</b>
+ <ol>
+ <li>Build your application as-is and install it on your Android 3.0 AVD (created above during
+<a href="#Setup">setup</a>).</li>
+ <li>Perform your usual tests to be sure everything works and looks as expected.</li>
+ </ol>
+ </li>
+
+ <li><b>Apply the new "holographic" theme to your application</b>
+ <ol>
+ <li>Open your manifest file and update the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element to
+set <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> to {@code "11"}. For example:
+<pre>
+<manifest ... >
+ <uses-sdk android:minSdkVersion="4"
+ android:targetSdkVersion="11" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+ <p>By targeting the Android 3.0 platform, the system automatically applies the holographic theme
+to each activity when your application runs on an Android 3.0 device. The holographic theme
+provides a new design for widgets, such as buttons and text boxes, and restyles other
+visual elements. This is the standard theme in applications built for Android 3.0, so your
+application will look more at home by enabling the theme.</p>
+ <p>Additionally, the holographic theme enables the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> in your activities when running on an
+Android 3.0 device. The Action Bar replaces the traditional title bar at the top of the activity
+window and provides the user access to the activity's Options Menu.</p>
+ </li>
+ <li>Continue to build your application against the minimum version specified by <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>,
+but install it on the Android 3.0 AVD. Repeat your tests to be sure that your user interface works
+well with the holographic theme.
+ <p class="note"><strong>Note:</strong> If you have applied other themes directly to your
+activities, they will override the inherited holographic theme. To resolve this, you can use
+the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
+version qualifier</a> to provide an alternative theme for Android 3.0 devices that's based on the
+holographic theme. For more information, read how to <a
+href="{@docRoot}guide/topics/ui/themes.html#SelectATheme">select a theme based on platform
+version</a>.</p>
+ </ol>
+ </li>
+
+ <li><b>Supply alternative layout resources for xlarge screens</b>
+ <p>By providing <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative
+resources</a> when running on extra large screens (using the <code>xlarge</code> resource
+qualifier), you can improve the user experience of your application on tablet-type devices without
+using new APIs.</p>
+ <p>For example, here are some things to consider when creating a new layout for extra large
+screens:</p>
+ <ul>
+ <li>Landscape layout: The "normal" orientation for tablet-type devices is usually landscape
+(wide), so you should be sure that your activities offer a layout that's optimized for a wide
+viewing area. <p>You can specify landscape resources with the <code>land</code> resource
+qualifier, but if you want alternative resources for an extra large landscape screen, you
+should use both <code>xlarge</code> and <code>land</code> qualifiers. For example, {@code
+res/layout-xlarge-land/}. The order of the qualifier names is important; see <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+Providing Alternative Resources</a> for more information.</p></li>
+ <li>Button position: Consider whether the position of the most common buttons in your UI are
+easily accessible while holding a tablet with two hands.</li>
+ <li>Font sizes: Be sure your application uses {@code sp} units when setting font
+sizes. This alone should ensure a readable experience on tablet-style devices. In some cases,
+however, you might want to consider larger font sizes for <code>xlarge</code> configurations.</li>
+ </ul>
+ <p>In general, always be sure that your application follows the <a
+href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
+for Screen Independence</a>.</p>
+ </li>
+</ol>
+
+
+
+
+
+<h2 id="Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</h2>
+
+<p>If you want to develop an application that's fully enhanced for tablet-type devices running
+Android 3.0, then you need to use new APIs in Android 3.0. This section introduces some of
+the new features you should use.</p>
+
+
+<h3>Declare the minimum system version</h3>
+
+<p>The first thing to do when you create a project for Android 3.0 is set your manifest's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+to {@code "11"}. For example:</p>
+
+<pre>
+<manifest ... >
+ <uses-sdk android:minSdkVersion="11" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+
+<p>By targeting the Android 3.0 platform, the system automatically applies the new holographic theme
+to each of your activities.</p>
+
+<p>Additionally, the holographic theme enables the Action Bar for each activity.</p>
+
+
+<h3>Use the Action Bar</h3>
+
+<p>The Action Bar is a widget for activities that replaces the traditional title bar at the top of
+the screen. By default, the Action Bar includes the application logo on the left side, followed by
+the activity title, and any available items from the Options Menu on the right side.</p>
+
+<p>You can enable items from your activity's Options Menu to appear directly in the Action Bar as
+"action items" by adding {@code showAsAction="ifRoom"} to specific items in your <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. You can also add
+navigation features to the Action Bar, such as tabs, and use the application icon to navigate to
+your application's "home" activity or "up" the activity hierarchy.</p>
+
+<p>For more information, read <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the
+Action Bar</a>.</p>
+
+
+
+<h3>Divide your activities into fragments</h3>
+
+<p>A fragment represents a behavior or a portion of user interface in an activity. You can combine
+multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple
+activities. You can think of a fragment as a modular section of an activity, which has its own
+lifecycle, receives its own input events, and which you can add or remove while the activity is
+running.</p>
+
+<p>For example, a news application can use one fragment to show a list of articles on the left and
+another fragment to display an article on the right—both fragments appear in one activity,
+side by side, and each fragment has its own set of lifecycle callback methods and handles its own
+input events. Thus, instead of using one activity to select an article and another activity to
+read the article, the user can select an article and read it all within the same activity.</p>
+
+<p>For more information, read the <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> document.</p>
+
+
+<h3>Use new animation APIs for transitions</h3>
+
+<p>An all new flexible animation framework allows you to animate arbitrary properties of any object
+(View, Drawable, Fragment, Object, or anything else). You can define several animation aspects
+(such as duration, repeat, interpolation, and more) for an object's int, float, and hexadecimal
+color values, by default. That is, when an object has a property field for one of these types, you
+can change its value over time to affect an animation.</p>
+
+<p>The {@link android.view.View} class also provides new APIs that leverage the new animation
+framework, allowing you to easily apply 2D and 3D transformations to views in your activity layout.
+New transformations are made possible with a set of object properties that define the view's layout
+position, orientation, transparency and more.</p>
+
+<p>For more information, read the <a
+href="{@docRoot}guide/topics/graphics/animation.html">Property Animation</a> document.</p>
+
+
+<h3>Enable hardware acceleration</h3>
+
+<p>You can now enable the OpenGL renderer for your application by setting {@code
+android:hardwareAccelerated="true"} in your manifest's <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
+element or for individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+<activity>}</a> elements. Hardware acceleration results in smoother animations, smoother
+scrolling, and overall better performance and response to user interaction. When enabled, be sure
+that you thoroughly test your application on a device that supports hardware acceleration.</p>
+
+
+<h3>Enhance your app widgets</h3>
+
+<p>App widgets allow users to access information from your application directly from the Home
+screen and interact with ongoing services (such as preview their email and control music playback).
+Android 3.0 enhances these capabilities by enabling collections, created with widgets such as
+{@link android.widget.ListView}, {@link android.widget.GridView}, and the new {@link
+android.widget.StackView}. These widgets allow you to create more interactive app
+widgets, such as one with a scrolling list, and can automatically update their data through a {@link
+android.widget.RemoteViewsService}.</p>
+
+<p>Additionally, you should create a preview image of your app widget using the Widget Preview
+application (pre-installed in an Android 3.0 AVD) and reference it with the {@link
+android.appwidget.AppWidgetProviderInfo#previewImage android:previewImage} attribute, so that users
+can see what the app widget looks like before adding it to their Home screen.</p>
+
+
+<h3>Add other new features</h3>
+
+<p>Android 3.0 introduces many more APIs that you might find valuable for your
+application, such as drag and drop APIs, new Bluetooth APIs, a system-wide clipboard framework, a
+new graphics engine called Renderscript, and more.</p>
+
+<p>To learn more about the APIs mentioned above and more, see the <a
+href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p>
+
+
+<h3>Publish your app for extra large screens</h3>
+
+<p>You should also decide whether your application is <em>only</em> for
+tablet-type devices (specifically, <em>xlarge</em> devices) or for all types of screen sizes.</p>
+
+<p>If you want your application to be available to all screen sizes (for example, for all
+phones and tablets), there's nothing you need to do. By default, an application with <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a> set to {@code "4"} or higher will resize to fit any screen size.</p>
+
+<p>If your application is <em>only</em> for <em>xlarge</em> screens, include the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element in your manifest and declare that the application supports
+only <em>xlarge</em> screens, by declaring all other sizes {@code "false"}. For example:</p>
+
+<pre>
+<manifest ... >
+ ...
+ <supports-screens android:smallScreens="false"
+ android:normalScreens="false"
+ android:largeScreens="false"
+ android:xlargeScreens="true" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+
+<p>With this declaration, you indicate that your application does not support any screen size except
+extra large. External services such as Android Market may then use this information to filter your
+application from devices that do not have an extra large screen.</p>
+
+
+
+<h3>Look at some samples</h3>
+
+<p>Many of the new features and APIs that are described in the <a
+href="{@docRoot}sdk/android-3.0.html#api">Android 3.0 Platform Preview</a> also have accompanying
+samples that can help you understand how to use them. To get the samples, download them from the SDK
+repository using the Android SDK Manager. After downloading the samples ("Samples for SDK API 11"),
+you can find them in <code><sdk_root>/samples/android-11/</code>. The links below can help you
+find samples for the features you are interested in:</p>
+
+<ul>
+ <li><a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>:
+Demonstrates many new APIs in Android 3.0, including fragments, the action bar, drag and drop, and
+animations.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
+Fragments</a>: Various samples that demonstrate fragment layouts, back stack, restoring state, and
+more.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.html"
+>Action Bar</a>: Samples that demonstrate various Action Bar features, such as tabs, logos, and
+action items.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.
+html">Clipboard</a>: An example of how to use the clipboard for copy and paste operations.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
+Drag and Drop</a>: An example of how to perform drag and drop with new View events.</li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List15.html">
+Multi-choice List</a>: An example of how to provide multiple-choice selection for ListView and
+GridView.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+Content Loaders</a>: An example using new Loader APIs to asynchronously load data.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
+Property Animation</a>: Several samples using the new animation APIs to animate object
+properties.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.
+html">Search View Widget</a>: Example using the new search widget in the Action Bar (as an
+"action view").</li>
+ <li><a
+href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript</a>: Contains several
+different applications that demonstrate using renderscript APIs for computations and 3D
+graphics.</li>
+</ul>
+
diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd
index 6842c82..6c88146 100644
--- a/docs/html/sdk/android-3.0.jd
+++ b/docs/html/sdk/android-3.0.jd
@@ -25,7 +25,7 @@
<h2>See Also</h2>
<ol>
- <li><a href="{@docRoot}sdk/preview/start.html">Getting Started</a></li>
+ <li><a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android 3.0</a></li>
</ol>
</div>
@@ -48,6 +48,10 @@
href="{@docRoot}sdk/android-{@sdkPlatformVersion}-highlights.html">Platform
Highlights</a>.</p>
+<p>Also see the <a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android
+3.0</a> document for information about how to optimize your existing applications for Android 3.0
+devices, even if you want to remain compatible with previous versions.</p>
+
<h2 id="relnotes">Revisions</h2>
@@ -294,8 +298,8 @@
android.widget.ListView}, and {@link android.widget.StackView} that are backed by remote data,
such as from a content provider.</p>
-<p>The {@link android.appwidget.AppWidgetProviderInfo} class (defined with an {@code
-<appwidget-provider> XML file) also supports two new fields: {@link
+<p>The {@link android.appwidget.AppWidgetProviderInfo} class (defined in XML with an {@code
+<appwidget-provider>} element) also supports two new fields: {@link
android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} and {@link
android.appwidget.AppWidgetProviderInfo#previewImage}. The {@link
android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} field lets you specify the view ID of the
@@ -351,10 +355,10 @@
loader for your activity or fragment.</p>
<p>For more information, read the <a
-href="{@docRoot}guide/topics/providers/loaders.html">Loaders</a> documentation. You can also see
+href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> documentation. You can also see
example code using loaders in the <a
-href="{@docRoot}samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">
-FragmentListCursorLoader</a> and <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentListCursorLoader.html">FragmentListCursorLoader</a>
+and <a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
LoaderThrottle</a> samples.</p>
diff --git a/docs/html/sdk/api_diff/11/changes.html b/docs/html/sdk/api_diff/11/changes.html
index 5166a8f..508ed16 100644
--- a/docs/html/sdk/api_diff/11/changes.html
+++ b/docs/html/sdk/api_diff/11/changes.html
@@ -4,7 +4,7 @@
<meta name="generator" content="JDiff v1.1.0">
<!-- Generated by the JDiff Javadoc doclet -->
<!-- (http://www.jdiff.org) -->
-<!-- on Tue Feb 08 11:41:20 PST 2011 -->
+<!-- on Sat Feb 19 17:19:55 PST 2011 -->
<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
<TITLE>
diff --git a/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
index 1be3b83..454d0d8 100644
--- a/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
@@ -1117,9 +1117,6 @@
<!-- Method getFragmentManager -->
<nobr><A HREF="android.app.Activity.html#android.app.Activity.getFragmentManager_added()" class="hiddenlink" target="rightframe"><b>getFragmentManager</b>
()</A></nobr><br>
-<!-- Method getGlobalProxyAdmin -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<!-- Method getIcon -->
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
()</A></nobr><br>
@@ -3058,9 +3055,6 @@
<nobr><A HREF="android.widget.Scroller.html#android.widget.Scroller.setFriction_added(float)" class="hiddenlink" target="rightframe">type <b>
(<code>float</code>)</b> in android.widget.Scroller
</A></nobr><br>
-<!-- Method setGlobalProxy -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List<String></code>)</A></nobr><br>
<!-- Method setGravity -->
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
@@ -3810,9 +3804,6 @@
<!-- Field USES_POLICY_EXPIRE_PASSWORD -->
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<!-- Field USES_POLICY_SETS_GLOBAL_PROXY -->
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<!-- Field valueFrom -->
<A NAME="V"></A>
<br><font size="+2">V</font>
diff --git a/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
index d62c2dc..c36382a 100644
--- a/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
@@ -1520,9 +1520,6 @@
<!-- Method getGlobalExternalFreedSize -->
<nobr><A HREF="android.os.Debug.html#android.os.Debug.getGlobalExternalFreedSize_changed()" class="hiddenlink" target="rightframe">getGlobalExternalFreedSize
()</A></nobr><br>
-<!-- Method getGlobalProxyAdmin -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<!-- Method getHost -->
<nobr><A HREF="android.net.Proxy.html#android.net.Proxy.getHost_changed(android.content.Context)" class="hiddenlink" target="rightframe">getHost
(<code>Context</code>)</A></nobr><br>
@@ -3923,9 +3920,6 @@
<!-- Method setGlobalAllocationLimit -->
<nobr><A HREF="android.os.Debug.html#android.os.Debug.setGlobalAllocationLimit_changed(int)" class="hiddenlink" target="rightframe">setGlobalAllocationLimit
(<code>int</code>)</A></nobr><br>
-<!-- Method setGlobalProxy -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List<String></code>)</A></nobr><br>
<!-- Method setGravity -->
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
@@ -4826,9 +4820,6 @@
<!-- Field USES_POLICY_EXPIRE_PASSWORD -->
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<!-- Field USES_POLICY_SETS_GLOBAL_PROXY -->
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<!-- Field valueFrom -->
<A NAME="V"></A>
<br><font size="+2">V</font>
diff --git a/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
index 0de6f00..79aaf10 100644
--- a/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
+++ b/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.attr.html b/docs/html/sdk/api_diff/11/changes/android.R.attr.html
index 3d896e1..b6cac99 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.attr.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.attr.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.dimen.html b/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
index ba8688f..205f3fc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.drawable.html b/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
index ddce2d3..8172aed 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.id.html b/docs/html/sdk/api_diff/11/changes/android.R.id.html
index 1ac126d..163425d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.id.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.id.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.layout.html b/docs/html/sdk/api_diff/11/changes/android.R.layout.html
index 85ae20e..a596cfd 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.layout.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.layout.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.string.html b/docs/html/sdk/api_diff/11/changes/android.R.string.html
index c28dc59..0e0f105 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.string.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.string.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.style.html b/docs/html/sdk/api_diff/11/changes/android.R.style.html
index 832221e..74ff759a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.style.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.style.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html b/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
index 5d39a581..f3c6626 100644
--- a/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html b/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
index 354ded0..58c532a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
+++ b/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Activity.html b/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
index 24ee0f8..96d728a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
index c14fb27..2823629 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
index 4163480..6c46ba7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
index 2bbac02..532eb6b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
index 0382b73..cb5c2f2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
index e5cb692..d6b69c0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html b/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
index a514fcb..fe83a77 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
index 24049ec..f85ec18 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
index f6de68c..3c138ad 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Notification.html b/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
index 1d0948f..19086f5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html b/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
index a66438b..fed6b615 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
index bf32ac5..7437921 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html b/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
index 9be408e..4621bf0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Service.html b/docs/html/sdk/api_diff/11/changes/android.app.Service.html
index bc2ce97..0bf322d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Service.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Service.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html b/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
index 308a055..42c6f8b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
index 8801ac5..1bb82b3 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -96,13 +96,6 @@
</TD>
<TD> </TD>
</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY"></A>
- <nobr><code>int</code> <A HREF="../../../../reference/android/app/admin/DeviceAdminInfo.html#USES_POLICY_SETS_GLOBAL_PROXY" target="_top"><code>USES_POLICY_SETS_GLOBAL_PROXY</code></A></nobr>
- </TD>
- <TD> </TD>
-</TR>
</TABLE>
</div>
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
index aebcd6f..28691bc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
index b54a22d..9527bda 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -83,13 +83,6 @@
</TH>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()"></A>
- <nobr><code>ComponentName</code> <A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#getGlobalProxyAdmin()" target="_top"><code>getGlobalProxyAdmin</code></A>()</nobr>
- </TD>
- <TD> </TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.app.admin.DevicePolicyManager.getPasswordExpiration_added(android.content.ComponentName)"></A>
<nobr><code>long</code> <A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#getPasswordExpiration(android.content.ComponentName)" target="_top"><code>getPasswordExpiration</code></A>(<code>ComponentName</code>)</nobr>
</TD>
@@ -174,13 +167,6 @@
</TR>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)"></A>
- <nobr><code>ComponentName</code> <A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#setGlobalProxy(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" target="_top"><code>setGlobalProxy</code></A>(<code>ComponentName,</nobr> Proxy<nobr>,</nobr> List<String><nobr><nobr></code>)</nobr>
- </TD>
- <TD> </TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.app.admin.DevicePolicyManager.setPasswordExpirationTimeout_added(android.content.ComponentName, long)"></A>
<nobr><code>void</code> <A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout(android.content.ComponentName, long)" target="_top"><code>setPasswordExpirationTimeout</code></A>(<code>ComponentName,</nobr> long<nobr><nobr></code>)</nobr>
</TD>
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
index 4f1a5b8..ec97611 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
index 88afafe..81585ba 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
index 36a3ce3..dbcbce2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html b/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
index 3ca03e3..e71af0f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html b/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
index 37e96ab..0c3d615 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html b/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
index eefe15d..526c923 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
index 1c60641..a1c2be1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
index 24de46c..569e158 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
index 0cbeea0..33c85fc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
index 98b3e0f..c5348d3 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.Context.html b/docs/html/sdk/api_diff/11/changes/android.content.Context.html
index 4c6b4eb..ae902c0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.Context.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.Context.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html b/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
index f3ac2cc..e7c38ce 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.Intent.html b/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
index f5abec5..20f5cf9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
index ff6a71d..b36c517 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
index c46e257..7d77e1b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html b/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
index 7fe598d..4b810a5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
index c00e677..d8b75aa 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
index 0514240..32c8de7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
index c79d5f9..cb1994e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
index 58341f9..f1a5385 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
index 5a6f4bf..42e668a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
index 14708d0..11536cb8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html b/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
index 5eaf4c8..a2c3198 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
index e8cf9e8..12811ed 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
index 4511dc1..2425924 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html b/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
index 1c4bda4..5df7634 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html b/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
index 0a1ed45..50284fb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html b/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
index d9fdcec..d5152d1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html b/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
index 628ce54..97436a2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
index 705a8cf..324912c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
index 259192d..779678d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
index c38367b..b782814 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
index e61a066..20aab20 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
index aae8194..aa6bc15 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
index 7bedb5d..ee6c8fb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html b/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
index 53d3fdb..68aa872 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html b/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
index bf25436..a4cf3e6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
index 2977fb3..b2dd308 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
index 09f7e5d..0b28b32 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
index 55990327..603d4e7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
index 6f5a1e6..7c69ecd 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
index 688fb54..d933421 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
index fa67596..f2edcf9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
index a8f2f56..32dfdde 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html b/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
index 6973a64..14d24ad 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
index 3cc8fcb..9769634 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
index f4bb841..83d5e9e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
index c025fc0..c6e749a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
index 5ce6d47..58490d8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html b/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
index 6a201ae..d946c68 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html b/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
index 0cda7ef..94a0784 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html b/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
index 53630fc..e99c6de 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
index 3bcc197..1035e58 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
index d4fb6cb..57241e2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html b/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
index c4053de..90d43f2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html b/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
index 14e94d0..3261b03 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Uri.html b/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
index 7bb8b183..c0afdd2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html b/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
index ba9366c..d49cd65 100644
--- a/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html b/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
index 3b6caca..6655d8ad 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html b/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
index 7c43f4c..832a5f0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
index 5c7e9be..14357aa 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html b/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
index a10c6ee..14964de 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Debug.html b/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
index e246dab2..7688959 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html b/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
index c52aa3e..0615328 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Environment.html b/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
index d442c3c..4c9554a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
index 11d58cb..3413c07 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
index 2a2d2a1..89cc546 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
index f6f67bc..91cacad 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html b/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
index 33e97af..eb400c0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html b/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
index 769be1f..68b1829 100644
--- a/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
+++ b/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html b/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
index 4818c3b..f4c2b97 100644
--- a/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
+++ b/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html b/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
index 378b739..56e510f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
index 8310d79..2297049 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
index 79a10ef..ee96c98 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
index 977cb16..584d98b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
index 5dd50fa..023a1dc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
index 245ccd6..4fe9e12 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
index 83cdcad..f4bf4d8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
index 8cd4f79..7071f67 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
index 93ecc6b..5817b98 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
index a4b9a61..5c83818 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
index 9c1624c..2988b8b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
index 8164d5b..986064e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
index a39f75f..7f2786a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
index e474257..e3b6975 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
index 4dc3604..795461f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
index cc8991c..fb3a818 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
index c46e247..91f1cc9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html b/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
index 027b99f..f0b2458 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
index 8a7dfac..017b8b7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
index 1069d4f..546a8a1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
index ed4c14c..d01ded8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html b/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
index b8d0f2de..528ba3e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html b/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
index abb12f2..ecd4ae2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
+++ b/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html b/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
index d052e33..13258f9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
index d29faf5..80b7071 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
index fa78a3d..44479f2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
index 242543a..ba731ba 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html b/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
index cfa9b82..58d4081 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.InputType.html b/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
index e1c90c7..0bc0783 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html b/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
index e5142ad..2b30205 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html b/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
index 04481b5..733ae32 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html b/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
index 874bc56..e8018ff 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html b/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
index 0a9d7d2..f8476bc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html b/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
index 6ce55bf..326579d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html b/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
index f7a04af..4c2a5af 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html b/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
index df81a2c..4e5829a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html b/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
index f33dc97..e4d3735 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html b/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
index 31db636..8985ccb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html b/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
index da2d421..3dd7be2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html b/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
index 0bf93e3..c40f954 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
index 9adcb31..945bee7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
index d46a5f7..07150bc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
index a8cb83a..7eab63e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html b/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
index 44fee2e0..384f01e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html b/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
index 4fa11b9..ae27c1d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html b/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
index 9a2994e..d5cb341 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html b/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
index 952c6f1..bc9da111 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Surface.html b/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
index 95daf0e..dfbfde3 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html b/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
index d97f6eb..409e310 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.View.html b/docs/html/sdk/api_diff/11/changes/android.view.View.html
index 97a38dc7..6de1ad7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.View.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.View.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html b/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
index c014d5c..c14d36f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html b/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
index 79646cd..9caa391 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html b/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
index 9bc54f5..73aa436 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Window.html b/docs/html/sdk/api_diff/11/changes/android.view.Window.html
index 62c3bb9..c55a207 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Window.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Window.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html b/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
index 15cf4ee..c68dce7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html b/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
index d2a593b..8bf383b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html b/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
index de6170c..c292c24 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
index 10a1b51..6104007 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
index 8dd751e..bd0e913 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
index 14a56f4..3a21f56 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
index 21c2053..1f8cd1e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
index c8e7c24..faa103b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
index 680e2fe..5e8ef7f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
index ae7396b..68a58d3 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
index 2924189..9ba6fb2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
index f85b0d2..0330d94 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
index 6a59505..d5dd2ca 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
index 023f085..dbd3c12 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
index 5f1bb1a..65172a0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html b/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
index 294126e..03dc6a1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
index 4480a6c..4dbdc6e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
index 4a58279..537dd79 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html b/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
index 64f70b5..2309fed 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html b/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
index 4ad3720..73b9dbc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html b/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
index 7eb3d5d..2658d25 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html b/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
index 29324a70..acdd2b7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html b/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
index 1f82834..922cbd7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html b/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
index 58c0677..9cc2fa8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html b/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
index 4aad339..f3aebe0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html b/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
index 1d6d6b7..de5f6eb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
index be2a0e2..53eef91 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
index 169abdd..a41e9df 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html b/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
index 340fbd0..b6e77be 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
index ba62dd3..602482b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html b/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
index 23773e8..e2ee047 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html b/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
index e63bee4..45488a7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html b/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
index 48e551e..780259e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/changes-summary.html b/docs/html/sdk/api_diff/11/changes/changes-summary.html
index a042283..b6af9ae 100644
--- a/docs/html/sdk/api_diff/11/changes/changes-summary.html
+++ b/docs/html/sdk/api_diff/11/changes/changes-summary.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html b/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
index e91f266..5bbc2a8 100644
--- a/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
+++ b/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/fields_index_additions.html b/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
index 8562538..12ecd4f 100644
--- a/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
@@ -1552,8 +1552,6 @@
</nobr><br>
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<A NAME="V"></A>
<br><font size="+2">V</font>
<a href="#A"><font size="-2">A</font></a>
diff --git a/docs/html/sdk/api_diff/11/changes/fields_index_all.html b/docs/html/sdk/api_diff/11/changes/fields_index_all.html
index a218b9c..52705a5 100644
--- a/docs/html/sdk/api_diff/11/changes/fields_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/fields_index_all.html
@@ -1633,8 +1633,6 @@
</nobr><br>
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<A NAME="V"></A>
<br><font size="+2">V</font>
<a href="#A"><font size="-2">A</font></a>
diff --git a/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html b/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
index 911563e..4ba7af5 100644
--- a/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
+++ b/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.lang.Object.html b/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
index 724f0e8..c894b07 100644
--- a/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
+++ b/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Deque.html b/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
index 221750f..1039093 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Locale.html b/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
index 8967c69..c27208e 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html b/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
index 74f15ba..e611d87 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html b/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
index e441b9d..7fbc133 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Queue.html b/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
index 29a1256..0595cfa 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
index a1e371a..a0f3777 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
index 232c8c0..3cf915b 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
index db430c4..044e5ca 100644
--- a/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
+++ b/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -71,7 +71,7 @@
<div id="doc-content" style="position:relative;">
<div id="mainBodyFluid">
<h1>API Change Statistics</h1>
-<p>The overall difference between API Levels 10 and 11 is approximately <span style="color:222;font-weight:bold;">2.57%</span>.
+<p>The overall difference between API Levels 10 and 11 is approximately <span style="color:222;font-weight:bold;">2.56%</span>.
</p>
<br>
<a name="numbers"></a>
@@ -110,24 +110,24 @@
</TR>
<TR>
<TD>Methods</TD>
- <TD ALIGN="right">433</TD>
+ <TD ALIGN="right">431</TD>
<TD ALIGN="right">100</TD>
<TD ALIGN="right">26</TD>
- <TD ALIGN="right">559</TD>
+ <TD ALIGN="right">557</TD>
</TR>
<TR>
<TD>Fields</TD>
- <TD ALIGN="right">620</TD>
+ <TD ALIGN="right">619</TD>
<TD ALIGN="right">36</TD>
<TD ALIGN="right">0</TD>
- <TD ALIGN="right">656</TD>
+ <TD ALIGN="right">655</TD>
</TR>
<TR>
<TD style="background-color:#FAFAFA"><b>Total</b></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1185</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1182</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>375</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>27</strong></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1587</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1584</strong></TD>
</TR>
</TABLE>
<br>
@@ -159,12 +159,12 @@
<TD><A HREF="pkg_android.html">android</A></TD>
</TR>
<TR>
- <TD ALIGN="center">15</TD>
- <TD><A HREF="pkg_android.app.admin.html">android.app.admin</A></TD>
+ <TD ALIGN="center">14</TD>
+ <TD><A HREF="pkg_android.preference.html">android.preference</A></TD>
</TR>
<TR>
<TD ALIGN="center">14</TD>
- <TD><A HREF="pkg_android.preference.html">android.preference</A></TD>
+ <TD><A HREF="pkg_android.app.admin.html">android.app.admin</A></TD>
</TR>
<TR>
<TD ALIGN="center">11</TD>
@@ -336,11 +336,6 @@
android.R.style</A></TD>
</TR>
<TR>
- <TD ALIGN="center">34</TD>
- <TD><A HREF="android.app.admin.DevicePolicyManager.html">
-android.app.admin.DevicePolicyManager</A></TD>
-</TR>
-<TR>
<TD ALIGN="center">33</TD>
<TD><A HREF="android.R.dimen.html">
android.R.dimen</A></TD>
@@ -361,6 +356,11 @@
android.widget.DatePicker</A></TD>
</TR>
<TR>
+ <TD ALIGN="center">32</TD>
+ <TD><A HREF="android.app.admin.DevicePolicyManager.html">
+android.app.admin.DevicePolicyManager</A></TD>
+</TR>
+<TR>
<TD ALIGN="center">30</TD>
<TD><A HREF="android.media.CamcorderProfile.html">
android.media.CamcorderProfile</A></TD>
@@ -762,11 +762,6 @@
</TR>
<TR>
<TD ALIGN="center">6</TD>
- <TD><A HREF="android.app.admin.DeviceAdminInfo.html">
-android.app.admin.DeviceAdminInfo</A></TD>
-</TR>
-<TR>
- <TD ALIGN="center">6</TD>
<TD><A HREF="android.media.MediaRecorder.AudioSource.html">
android.media.MediaRecorder.AudioSource</A></TD>
</TR>
@@ -867,6 +862,11 @@
</TR>
<TR>
<TD ALIGN="center">4</TD>
+ <TD><A HREF="android.app.admin.DeviceAdminInfo.html">
+android.app.admin.DeviceAdminInfo</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">4</TD>
<TD><A HREF="android.appwidget.AppWidgetHost.html">
android.appwidget.AppWidgetHost</A></TD>
</TR>
diff --git a/docs/html/sdk/api_diff/11/changes/methods_index_additions.html b/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
index ba21317..b3a67ab 100644
--- a/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
@@ -430,8 +430,6 @@
()</A></nobr><br>
<nobr><A HREF="android.app.Activity.html#android.app.Activity.getFragmentManager_added()" class="hiddenlink" target="rightframe"><b>getFragmentManager</b>
()</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
()</A></nobr><br>
<nobr><A HREF="android.text.method.QwertyKeyListener.html#android.text.method.QwertyKeyListener.getInstanceForFullKeyboard_added()" class="hiddenlink" target="rightframe"><b>getInstanceForFullKeyboard</b>
@@ -1273,8 +1271,6 @@
<nobr><A HREF="android.widget.Scroller.html#android.widget.Scroller.setFriction_added(float)" class="hiddenlink" target="rightframe">type <b>
(<code>float</code>)</b> in android.widget.Scroller
</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List<String></code>)</A></nobr><br>
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
<i>setIcon</i><br>
diff --git a/docs/html/sdk/api_diff/11/changes/methods_index_all.html b/docs/html/sdk/api_diff/11/changes/methods_index_all.html
index 79ac20a..2f1d865 100644
--- a/docs/html/sdk/api_diff/11/changes/methods_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/methods_index_all.html
@@ -544,8 +544,6 @@
()</A></nobr><br>
<nobr><A HREF="android.os.Debug.html#android.os.Debug.getGlobalExternalFreedSize_changed()" class="hiddenlink" target="rightframe">getGlobalExternalFreedSize
()</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<nobr><A HREF="android.net.Proxy.html#android.net.Proxy.getHost_changed(android.content.Context)" class="hiddenlink" target="rightframe">getHost
(<code>Context</code>)</A></nobr><br>
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
@@ -1590,8 +1588,6 @@
</A></nobr><br>
<nobr><A HREF="android.os.Debug.html#android.os.Debug.setGlobalAllocationLimit_changed(int)" class="hiddenlink" target="rightframe">setGlobalAllocationLimit
(<code>int</code>)</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List<String></code>)</A></nobr><br>
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
<i>setIcon</i><br>
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html b/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
index f52f77d..b2a2812 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html b/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
index ab6c604..54220b1 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.app.html b/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
index d251b5c..da5df6f 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html b/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
index 4ca6abc..d3df6f3 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html b/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
index 95550d7..286de69 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
index b409999..814b57c 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
index 5e599e6..e791cbc 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
index 6801657..1966151 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.database.html b/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
index fe1f8d4..94564d3 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html b/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
index bc66f4b..7200032 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
index afe6b4a..18d15cc 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
index 74c158e..4f1c440 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
index f542030..ea84a38 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.html b/docs/html/sdk/api_diff/11/changes/pkg_android.html
index 5e25eb4..29df82c 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html b/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
index 699635b..d2c4e27 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.media.html b/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
index b7352581..2cd99a5 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.net.html b/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
index 8c89b35..e1e2bf5 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html b/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
index 4cbf960..f871db5 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.os.html b/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
index a76e62c..eedacd3 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html b/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
index c7e1fe9..35ef0bc 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
index c273c1c..842355e 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
index dfcd56f..e981387 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
index d9cec6b..f0bde9f 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html b/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
index c6263c4..8a2d08b 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.test.html b/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
index 9d746cb..39db204 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html b/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
index 105c032..45914ea 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
index 48429be..cc395ca 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
index 7be7925..0d47282 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
index 9bf1ec4..eefed4b 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.util.html b/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
index 99e977b7..b6444ba 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
index b12ffa3..3fd23d1 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
index 6f31108..2ec022d 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
index 44d3371..d7f85e0 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
index efbfcaa..0fd65d3 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
index 6ba274e..64f2bc2 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html b/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
index 18325d7..6479d33 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html b/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
index 075dadc..9415d76 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_java.util.html b/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
index 4f6d8a0..461d0ac 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
@@ -54,7 +54,7 @@
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index c283167..3a7b39f 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
-adt.zip.version=9.0.0
-adt.zip.download=ADT_9.0.0.zip
-adt.zip.bytes=4433536
-adt.zip.checksum=bc2757f2a5a11d131390ce547bae154b
+adt.zip.version=10.0.0
+adt.zip.download=ADT-10.0.0.zip
+adt.zip.bytes=4243777
+adt.zip.checksum=bf88bff62bc45c3b6d062e2beed67765
@jd:body
@@ -116,22 +116,27 @@
<ul>
<li>The tools now automatically generate Java Programming Language source files (in the <code>gen/</code> directory) and
bytecode (in the <code>res/raw/</code> directory) from your <code>.rs</code> files.</li>
- <li>A Binary XML editor has been added.</li>
+ <li>A Binary XML editor has been added (<a href="http://tools.android.com/recent/binaryxmleditor">details</a>).</li>
<li>Traceview is now integrated into the Eclipse UI (<a href="http://tools.android.com/recent/traceviewineclipse">details</a>).</li>
<li>The "Go To Declaration" feature for XML and <code>.java</code> files quickly show all the matches in the project
- and allows you jump to specific items such as string translations or <code>onClick</code> handlers.</li>
- <li>The Resource Chooser can create items such as dimensions, integers, ids, and booleans.</li>
+ and allows you jump to specific items such as string translations or <code>onClick</code> handlers
+ (<a href="http://tools.android.com/recent/gotodeclarationimprovements">details</a>).</li>
+ <li>The Resource Chooser can create items such as dimensions, integers, ids, and booleans
+ (<a href="http://tools.android.com/recent/resourcechoosercannowcreatearbitraryvalues">details</a>).</li>
<li>Improvements to the Visual Layout Editor:
<ul>
<li>A new Palette with categories and rendering previews
(<a href="http://tools.android.com/recent/newpalette">details</a>).</li>
- <li>A Layout action bar.</li>
+ <li>A Layout Actions bar that provides quick access to common layout operations
+ (<a href="http://tools.android.com/recent/layoutactionsbar">details</a>).</li>
<li>When the Android 3.0 rendering library is selected, layouts render more like they do on devices.
This includes rendering of status and title bars to more accurately reflect the actual
- screen space available to applications.</li>
+ screen space available to applications
+ (<a href="http://tools.android.com/recent/systembarandactionbar">details</a>).</li>
<li>Zoom improvements such as fit to view, persistent scale, and keyboard access.
(<a href="http://tools.android.com/recent/zoomimprovements">details</a>).</li>
- <li>Further improvements to <code><merge></code> layouts, as well as layouts with gesture overlays.</li>
+ <li>Further improvements to <code><merge></code> layouts, as well as layouts with gesture overlays
+ (<a href="http://tools.android.com/recent/improvedsupportformergetags">details</a>).</li>
<li>Improved rendering error diagnostics.</li>
</ul>
</li>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 1b4a336..df8869e 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_installer=installer_r09-windows.exe
-sdk.win_installer_bytes=32828818
-sdk.win_installer_checksum=ef92e643731f820360e036eb11658656
+sdk.win_installer=installer_r10-windows.exe
+sdk.win_installer_bytes=32845713
+sdk.win_installer_checksum=4e4356c472a6271ac9c062df0219dcb3
-sdk.win_download=android-sdk_r09-windows.zip
-sdk.win_bytes=32779808
-sdk.win_checksum=1a1bb8fad80bcc2dfbd00443b9a13e6b
+sdk.win_download=android-sdk_r10-windows.zip
+sdk.win_bytes=30112516
+sdk.win_checksum=643a75d99f5d4ca39dcf743fe894d599
-sdk.mac_download=android-sdk_r09-mac_x86.zip
-sdk.mac_bytes=28829553
-sdk.mac_checksum=ef3102fdbbbbd9bf4d9b572624aa9dc1
+sdk.mac_download=android-sdk_r10-mac_x86.zip
+sdk.mac_bytes=28224540
+sdk.mac_checksum=4d0a99a458e4f4bde65a01f8545f27e9
-sdk.linux_download=android-sdk_r09-linux_x86.tgz
-sdk.linux_bytes=26917824
-sdk.linux_checksum=9fefac5ff85d329836439f6e77a78cae
+sdk.linux_download=android-sdk_r10-linux_x86.tgz
+sdk.linux_bytes=26556013
+sdk.linux_checksum=10cafdd44771bfe2ba9d4440886389e7
@jd:body
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 10887c6..40231a3 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -1,16 +1,16 @@
ndk=true
-ndk.win_download=android-ndk-r5b-windows.zip
-ndk.win_bytes=61299831
-ndk.win_checksum=87745ada305ab639399161ab4faf684c
+ndk.win_download=android-ndk-r6-windows.zip
+ndk.win_bytes=64147764
+ndk.win_checksum=771b56328b7fc7751aa8040fb9dd09f0
-ndk.mac_download=android-ndk-r5b-darwin-x86.tar.bz2
-ndk.mac_bytes=50210863
-ndk.mac_checksum=019a14622a377b3727ec789af6707037
+ndk.mac_download=android-ndk-r6-darwin-x86.tar.bz2
+ndk.mac_bytes=50244722
+ndk.mac_checksum=d107f6d63478b73e09ed2eecd4c62bd3
-ndk.linux_download=android-ndk-r5b-linux-x86.tar.bz2
-ndk.linux_bytes=44138539
-ndk.linux_checksum=4c0045ddc2bfd657be9d5177d0e0b7e7
+ndk.linux_download=android-ndk-r6-linux-x86.tar.bz2
+ndk.linux_bytes=44088689
+ndk.linux_checksum=c83c3ab5a5e5a3b3fe7b907735ce77d4
page.title=Android NDK
@jd:body
diff --git a/docs/html/sdk/preview/start.jd b/docs/html/sdk/preview/start.jd
deleted file mode 100644
index 3bf70b3..0000000
--- a/docs/html/sdk/preview/start.jd
+++ /dev/null
@@ -1,294 +0,0 @@
-page.title=Getting Started with the Android 3.0 Preview
-@jd:body
-
-<p>Welcome to Android 3.0!</p>
-
-<p>Android 3.0 is the next major release of the Android platform and is optimized for larger screen
-devices, particularly tablets. We're offering a preview SDK so you can get a head-start developing
-applications for it or simply test and optimize your existing application for upcoming devices.</p>
-
-<p><strong>Be aware that:</strong></p>
-<ul>
- <li>The APIs in the preview SDK are <strong>not final</strong>. Some APIs may change in behavior
-or availability when the final SDK is made available.</li>
- <li>You <strong>cannot</strong> publish an application that's built against the preview
-SDK—you can only run an application built against the preview SDK on the Android
-emulator.</li>
- <li>The documentation on <a href="http://developer.android.com">developer.android.com</a>
-does <strong>not</strong> include the Android 3.0 documentation—to read the API reference and
-developer guides for Android 3.0, you must install the Android 3.0 preview documentation from
-the AVD and SDK Manager.</li>
-</ul>
-
-
-
-<h3>How do I start?</h3>
-
-<ol>
- <li><a href="#Setup">Set up the preview SDK</a></li>
- <li>Then choose your app adventure:
- <ol type="a">
- <li><a href="#Optimize">Optimize Your App for Tablets and Similar Devices</a>
- <p>When you have an existing application and you want to maintain compatibility with
-older versions of Android.</p>
- </li>
- <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</a>
- <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
- create a new application targeted to tablets and similar devices.</p></li>
- </ol>
- </li>
-</ol>
-
-<h3>Code samples</h3>
-<p>Many of the new features and APIs that are described in the <a href="{@docRoot}sdk/android-3.0.html#api">
-Android 3.0 Platform Preview</a> also have accompanying samples that help you understand how to use them.
-To get the samples, download them from the SDK repository using the Android SDK Manager. After download
-the samples are located in <code><sdk_root>/samples/android-Honeycomb</code>. The list of links
-below helps you find samples for the features you are interested in:</p>
-<ul>
- <li><a href="{@docRoot}resources/samples/Honeycomb-Gallery/index.html">Honeycomb Gallery</a> -
- A demo application highlighting how to use some of the new APIs in Honeycomb, including fragments, the action bar,
- drag and drop, transition animations, and a stack widget.</li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">Fragments</a>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.html">Action Bar</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.html">Clipboard</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">Drag and Drop</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List15.html">
- Multiple-choice selection for ListView and GridView</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">Content Loaders</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">Property Animation</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">Search View Widget</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/PopupMenu1.html">Popup Menu Widget</a></li>
-</ul>
-
-
-<h2 id="Setup">Set Up the Preview SDK</h2>
-
-<p>To start using the Android 3.0 preview SDK, set up your existing Android SDK with the new
-platform:</p>
-<p>(If you don't have an existing SDK, <a href="{@docRoot}sdk/index.html">download it
-now</a>.)</p>
-<ol>
- <li><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
-Manager</a> and install the following:
- <ul>
- <li>SDK Platform Android 3.0 Preview</li>
- <li>Android SDK Tools, revision 9</li>
- <li>Documentation for Android 'Honeycomb' Preview</li>
- <li>Samples for SDK API Honeycomb Preview</li>
- </ul>
- </li>
- <li><a href="{@docRoot}guide/developing/other-ide.html#AVD">Create an AVD</a> for tablets: set
-the target to "Android 3.0 (Preview)" and the skin to "WXGA".</li>
-</ol>
-
-
-<h3>About emulator performance</h3>
-
-<p>Because the Android emulator must simulate the ARM instruction set architecture on your
-computer and the WXGA screen is significantly larger than what the emulator
-normally handles, emulator performance is much slower than usual.</p>
-
-<p>In particular, initializing the emulator can be slow and can take several
-minutes, depending on your hardware. When the emulator is booting there is
-limited user feedback, so please be patient and continue waiting until you see
-the home screen appear. </p>
-
-<p>Note that you do not need to do a full boot of your emulator each time you
-rebuild your application — typically you only need to boot at the start of
-a session. See the Tips section below for information about using Snapshots to
-cut startup time after first initialization. </p>
-
-<p>We're working hard to resolve the performance issues and it will improve in future releases.
-Unfortunately, the emulator will perform slowly during your trial with the preview SDK. For the time
-being, the emulator is still best way to evaluate your application's appearance and functionality on
-Android 3.0.</p>
-
-<p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable
-snapshots for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in
-the GUI). Then, start the AVD from the manager and check <b>Launch from snapshot</b> and <b>Save to
-snapshot</b>. This way, when you close the emulator, a snapshot of the AVD state is saved and
-used to quickly relaunch the AVD next time. However, when you choose to save a snapshot, the
-emulator will be slow to close, so you might want to enable <b>Save to
-snapshot</b> only for the first time you launch the AVD.</p>
-
-
-<h3>Known issues</h3>
-
-<p>The following known issues occur for Android 3.0 AVDs that are loaded in the emulator:</p>
- <ul>
- <li>You cannot take screenshots of an emulator screen. The Device Screen
- Capture window displays <strong>Screen not available</strong>.</li>
- <li>The emulator cannot receive incoming SMS messages.</li>
- <li>GPS emulation is currently not supported.</li>
- <li>When rotating the emulator screen by pressing Ctrl-F11, the screen turns green momentarily,
-then displays the normal interface.</li>
- <li>In some circumstances, the emulator displays a rotated portrait screen while in landscape
-mode. To view the screen correctly, rotate the emulator to portrait mode by pressing Ctrl-F11 or
-turn off the auto-rotate setting in <strong>Settings > Screen > Auto-rotate screen</strong>.</li>
- <li>The Dev Tools application sometimes crashes when trying to use the Package Browser
-feature.</li>
- <li>On Ubuntu 10.04 64-bit machines, you cannot create an AVD that has an SD card.</li>
- </ul>
-
-
-
-<h2 id="Optimize">Optimize Your Application for Tablets and Similar Devices</h2>
-
-<p>If you've already developed an application for Android, there are a few things you can do
-to optimize it for a tablet-style experience, without changing the minimum platform version required
-(you don't need to change the manifest {@code minSdkVersion}).</p>
-
-<p class="note"><strong>Note:</strong> All Android applications are forward-compatible, so
-there's nothing you <em>have to</em> do—if your application is a good citizen of the Android
-APIs, your app should work fine on devices running Android 3.0. However, in order to provide users
-a better experience when running your app on an Android 3.0 tablet or similar-size device, we
-recommend that you update your application to adapt to the new system theme and optimize your
-application for larger screens.</p>
-
-<p>Here's what you can do to optimize your application for tablets running Android
-3.0:</p>
-
-<ol>
- <li><b>Test your current application on Android 3.0</b>
- <ol>
- <li>Build your application as-is and install it on your WXGA AVD (created above).</li>
- <li>Perform your usual tests to be sure everything works and looks as expected.</li>
- </ol>
- </li>
-
- <li><b>Apply the new "holographic" theme to your application</b>
- <ol>
- <li>Open your manifest file and update the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element to
-set {@code android:targetSdkVersion} to {@code "Honeycomb"}. For example:
-<pre>
-<manifest ... >
- <uses-sdk android:minSdkVersion="4"
- android:targetSdkVersion="Honeycomb" />
- <application ... >
- ...
- <application>
-</manifest>
-</pre>
- <p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
-Level that is valid only while testing against the preview SDK. You
-<strong>should not</strong> publish your application using this API Level. When the final version of
-the Android 3.0 SDK is made available, you must change this value to the real API Level that will be
-specified for Android 3.0. For more information, read about <a
-href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
- <p>By targeting the Android 3.0 platform, the system automatically applies the Holographic theme
-to each of your activities, when running on an Android 3.0 device.</p>
- </li>
- <li>Continue to build against your application's {@code minSdkVersion}, but install it
-on the Android 3.0 AVD. Perform more testing on your application to be sure that your user interface
-works well with the Holographic theme.
- <p class="note"><strong>Note:</strong> If you've applied themes to your activities already,
-they will override the Holographic theme that the system applies when you set the {@code
-android:targetSdkVersion} to {@code "Honeycomb"}.
-Once the Android 3.0 APIs are finalized and an official API Level is assigned, you can use
-the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
-version qualifier</a> to provide an alternative theme that's based on the Holographic theme when
-your application is running on Android 3.0.</p>
- </ol>
- </li>
-
- <li><b>Supply alternative layout resources for xlarge screens</b>
- <p>As discussed in the guide to <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>, Android
-2.3 and above support the <code>xlarge</code> resource qualifier, which you should use to supply
-alternative layouts for extra large screens.</p>
- <p>By providing alternative layouts for some of your activities when running on extra large
-screens, you can improve the user experience of your application on a tablet without using any
-new APIs.</p>
- <p>For example, here are some things to consider when creating a new layout for tables:</p>
- <ul>
- <li>Landscape layout: The "normal" orientation for tablets is usually landscape (wide), so
-you should be sure that your activities offer an appropriate layout for such a wide viewing
-area.</li>
- <li>Button position: Consider whether the position of the most common buttons in your UI are
-easily accessible while holding a tablet with two hands.</li>
- </ul>
- </li>
-</ol>
-
- <p>In general, always be sure that your application follows the <a
-href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
-for Screen Independence</a>.</p>
-
-
-<h2 id="Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</h2>
-
-<p>If you want to develop something truly for tablet-type devices running Android 3.0, then you need
-to use new APIs available in Android 3.0. This section introduces some of the new features that you
-should use.</p>
-
-<p>The first thing to do when you create a project with the Android 3.0 preview is set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element to
-use {@code "Honeycomb"} for the {@code android:minSdkVersion}. For example:</p>
-
-<pre>
-<manifest ... >
- <uses-sdk android:minSdkVersion="Honeycomb" />
- <application ... >
- ...
- <application>
-</manifest>
-</pre>
-
-<p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
-Level that is valid only while building and testing against the preview SDK. You
-<strong>cannot</strong> publish your application using this API Level. When the final version of the
-Android 3.0 SDK is made available, you must change this value to the real API Level that is
-specified for Android 3.0. For more information, read about <a
-href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
-
-<p>Be sure that the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
-<uses-sdk>}</a> element appears <strong>before</strong> the <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
-element.</p>
-
-<p>By targeting the Android 3.0 platform (and declaring it before <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>),
-the system automatically applies the new Holographic theme to each of your
-activities.</p>
-
-
-
-<h3>Publishing your app for tablet-type devices only</h3>
-
-<p>Additionally, you should decide whether your application is for <em>only</em> tablet devices
-(specifically, <em>xlarge</em> devices) or for devices of all sizes that may run Android 3.0.</p>
-
-<p>If your application is <em>only</em> for tablets (<em>xlarge</em> screens; not for mobile
-devices/phones), then you should include the <a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
-<supports-screens>}</a> element in your manifest with all sizes except for xlarge declared
-false. For example:</p>
-
-<pre>
-<manifest ... >
- <uses-sdk android:minSdkVersion="Honeycomb" />
- <supports-screens android:smallScreens="false"
- android:normalScreens="false"
- android:largeScreens="false"
- android:xlargeScreens="true" />
- <application ... >
- ...
- <application>
-</manifest>
-</pre>
-
-<p>With this declaration, you indicate that your application does not support any screen size except
-extra large. External services such as Android Market may use this to filter your application
-from devices that do not have an extra large screen.</p>
-
-<p>Otherwise, if you want your application to be available to both small devices (phones) and large
-devices (tablets), do <em>not</em> include the <a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
-<supports-screens>}</a> element.</p>
-
-<div class="special">
-<p>To learn more about some of the new APIs,
-see the <a href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform Preview</a> document.</p>
-</div>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 1b94b2c..c1894d8 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -80,6 +80,7 @@
<div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
<span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div>
<ul>
+ <li><a href="<?cs var:toroot ?>sdk/android-3.0-optimize.html">Optimizing Apps for 3.0</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/11/changes.html">API Differences Report »</a></li>
</ul>
@@ -88,10 +89,17 @@
<div><a href="<?cs var:toroot ?>sdk/android-2.3.3.html">
<span class="en">Android 2.3.3 Platform</span></a> <span class="new">new!</span></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report »</a></li>
</ul>
</li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
+ <span class="en">Android 2.3 Platform</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report »</a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li>
@@ -99,13 +107,6 @@
<li class="toggle-list">
<div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div>
<ul>
- <li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
- <span class="en">Android 2.3 Platform</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report »</a></li>
- </ul>
- </li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index b2f4379..12dc93c 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -19,7 +19,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
-
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
@@ -342,7 +341,7 @@
}
long bufferSize = (long)elements << shift;
- long pixelSize = (long)getRowBytes() * getHeight();
+ long pixelSize = getByteCount();
if (bufferSize < pixelSize) {
throw new RuntimeException("Buffer not large enough for pixels");
@@ -378,7 +377,7 @@
}
long bufferBytes = (long)elements << shift;
- long bitmapBytes = (long)getRowBytes() * getHeight();
+ long bitmapBytes = getByteCount();
if (bufferBytes < bitmapBytes) {
throw new RuntimeException("Buffer not large enough for pixels");
@@ -822,6 +821,14 @@
}
/**
+ * Returns the number of bytes used to store this bitmap's pixels.
+ */
+ public final int getByteCount() {
+ // int result permits bitmaps up to 46,340 x 46,340
+ return getRowBytes() * getHeight();
+ }
+
+ /**
* If the bitmap's internal config is in one of the public formats, return
* that config, otherwise return null.
*/
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index d8a7f9d..0a23bae 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1254,9 +1254,7 @@
* @param text The text to measure
* @param index The offset into text to begin measuring at
* @param count The number of maximum number of entries to measure. If count
- * is negative, then the characters before index are measured
- * in reverse order. This allows for measuring the end of
- * string.
+ * is negative, then the characters are measured in reverse order.
* @param maxWidth The maximum width to accumulate.
* @param measuredWidth Optional. If not null, returns the actual width
* measured.
diff --git a/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java b/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java
index 6734bb7..685a998 100644
--- a/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java
@@ -16,8 +16,6 @@
package android.graphics;
-import android.graphics.Bitmap;
-import android.graphics.Color;
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -42,6 +40,10 @@
assertEquals("rowbytes", 200, bm2.getRowBytes());
assertEquals("rowbytes", 200, bm3.getRowBytes());
+ assertEquals("byteCount", 80000, bm1.getByteCount());
+ assertEquals("byteCount", 40000, bm2.getByteCount());
+ assertEquals("byteCount", 40000, bm3.getByteCount());
+
assertEquals("height", 200, bm1.getHeight());
assertEquals("height", 200, bm2.getHeight());
assertEquals("height", 200, bm3.getHeight());
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index d484d60..9e6f0e2 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -18,15 +18,17 @@
#define AUDIO_SOURCE_H_
+#include <media/AudioRecord.h>
#include <media/AudioSystem.h>
#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <utils/List.h>
namespace android {
class AudioRecord;
-struct MediaBufferGroup;
-struct AudioSource : public MediaSource {
+struct AudioSource : public MediaSource, public MediaBufferObserver {
// Note that the "channels" parameter is _not_ the number of channels,
// but a bitmask of AudioSystem::audio_channels constants.
AudioSource(
@@ -45,6 +47,9 @@
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
+ status_t dataCallbackTimestamp(const AudioRecord::Buffer& buffer, int64_t timeUs);
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
protected:
virtual ~AudioSource();
@@ -54,27 +59,31 @@
// After the initial mute, we raise the volume linearly
// over kAutoRampDurationUs.
- kAutoRampDurationUs = 700000,
+ kAutoRampDurationUs = 300000,
// This is the initial mute duration to suppress
// the video recording signal tone
- kAutoRampStartUs = 1000000,
- };
+ kAutoRampStartUs = 0,
+ };
+
+ Mutex mLock;
+ Condition mFrameAvailableCondition;
+ Condition mFrameEncodingCompletionCondition;
AudioRecord *mRecord;
status_t mInitCheck;
bool mStarted;
+ int32_t mSampleRate;
- bool mCollectStats;
bool mTrackMaxAmplitude;
int64_t mStartTimeUs;
int16_t mMaxAmplitude;
int64_t mPrevSampleTimeUs;
- int64_t mTotalLostFrames;
- int64_t mPrevLostBytes;
int64_t mInitialReadTimeUs;
+ int64_t mNumFramesReceived;
+ int64_t mNumClientOwnedBuffers;
- MediaBufferGroup *mGroup;
+ List<MediaBuffer * > mBuffersReceived;
void trackMaxAmplitude(int16_t *data, int nSamples);
@@ -84,6 +93,9 @@
int32_t startFrame, int32_t rampDurationFrames,
uint8_t *data, size_t bytes);
+ void releaseQueuedFrames_l();
+ void waitOutstandingEncodingFrames_l();
+
AudioSource(const AudioSource &);
AudioSource &operator=(const AudioSource &);
};
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 31a549c..66dfff6 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -38,6 +38,7 @@
extern const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW;
extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
extern const char *MEDIA_MIMETYPE_AUDIO_FLAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
extern const char *MEDIA_MIMETYPE_CONTAINER_WAV;
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 2012fcc..86ce098 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -28,6 +28,10 @@
#include <utils/RefBase.h>
#include <utils/String8.h>
+#ifdef HAVE_ANDROID_OS
+class SkMatrix;
+#endif
+
/*
* Additional private constants not defined in ndk/ui/input.h.
*/
@@ -79,6 +83,10 @@
namespace android {
+#ifdef HAVE_ANDROID_OS
+class Parcel;
+#endif
+
/*
* Flags that flow alongside events in the input dispatch system to help with certain
* policy decisions such as waking from device sleep.
@@ -162,15 +170,30 @@
* Pointer coordinate data.
*/
struct PointerCoords {
- float x;
- float y;
- float pressure;
- float size;
- float touchMajor;
- float touchMinor;
- float toolMajor;
- float toolMinor;
- float orientation;
+ enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
+
+ // Bitfield of axes that are present in this structure.
+ uint64_t bits;
+
+ // Values of axes that are stored in this structure packed in order by axis id
+ // for each axis that is present in the structure according to 'bits'.
+ float values[MAX_AXES];
+
+ inline void clear() {
+ bits = 0;
+ }
+
+ float getAxisValue(int32_t axis) const;
+ status_t setAxisValue(int32_t axis, float value);
+ float* editAxisValue(int32_t axis);
+
+#ifdef HAVE_ANDROID_OS
+ status_t readFromParcel(Parcel* parcel);
+ status_t writeToParcel(Parcel* parcel) const;
+#endif
+
+private:
+ void tooManyAxes(int axis);
};
/*
@@ -185,12 +208,13 @@
inline int32_t getDeviceId() const { return mDeviceId; }
inline int32_t getSource() const { return mSource; }
-
+
+ inline void setSource(int32_t source) { mSource = source; }
+
protected:
void initialize(int32_t deviceId, int32_t source);
void initialize(const InputEvent& from);
-private:
int32_t mDeviceId;
int32_t mSource;
};
@@ -241,7 +265,7 @@
nsecs_t eventTime);
void initialize(const KeyEvent& from);
-private:
+protected:
int32_t mAction;
int32_t mFlags;
int32_t mKeyCode;
@@ -263,12 +287,18 @@
inline int32_t getAction() const { return mAction; }
+ inline void setAction(int32_t action) { mAction = action; }
+
inline int32_t getFlags() const { return mFlags; }
inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+ inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
+
inline int32_t getMetaState() const { return mMetaState; }
+ inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
+
inline float getXOffset() const { return mXOffset; }
inline float getYOffset() const { return mYOffset; }
@@ -285,48 +315,54 @@
inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+ const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
+
+ float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
+
inline float getRawX(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).x;
+ return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
}
inline float getRawY(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).y;
+ return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
}
+ float getAxisValue(int32_t axis, size_t pointerIndex) const;
+
inline float getX(size_t pointerIndex) const {
- return getRawX(pointerIndex) + mXOffset;
+ return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
}
inline float getY(size_t pointerIndex) const {
- return getRawY(pointerIndex) + mYOffset;
+ return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
}
inline float getPressure(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).pressure;
+ return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
}
inline float getSize(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).size;
+ return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
}
inline float getTouchMajor(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).touchMajor;
+ return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
}
inline float getTouchMinor(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).touchMinor;
+ return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
}
inline float getToolMajor(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).toolMajor;
+ return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
}
inline float getToolMinor(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).toolMinor;
+ return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
}
inline float getOrientation(size_t pointerIndex) const {
- return getCurrentPointerCoords(pointerIndex).orientation;
+ return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
}
inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
@@ -335,48 +371,67 @@
return mSampleEventTimes[historicalIndex];
}
+ const PointerCoords* getHistoricalRawPointerCoords(
+ size_t pointerIndex, size_t historicalIndex) const;
+
+ float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+ size_t historicalIndex) const;
+
inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+ return getHistoricalRawAxisValue(
+ AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
}
inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+ return getHistoricalRawAxisValue(
+ AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
}
+ float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
+
inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
}
inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
}
inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
}
inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
}
inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
}
inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
}
inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
}
inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
}
inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
+ return getHistoricalAxisValue(
+ AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
}
void initialize(
@@ -396,12 +451,23 @@
const int32_t* pointerIds,
const PointerCoords* pointerCoords);
+ void copyFrom(const MotionEvent* other, bool keepHistory);
+
void addSample(
nsecs_t eventTime,
const PointerCoords* pointerCoords);
void offsetLocation(float xOffset, float yOffset);
+ void scale(float scaleFactor);
+
+#ifdef HAVE_ANDROID_OS
+ void transform(const SkMatrix* matrix);
+
+ status_t readFromParcel(Parcel* parcel);
+ status_t writeToParcel(Parcel* parcel) const;
+#endif
+
// Low-level accessors.
inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
@@ -409,7 +475,7 @@
return mSamplePointerCoords.array();
}
-private:
+protected:
int32_t mAction;
int32_t mFlags;
int32_t mEdgeFlags;
@@ -422,15 +488,6 @@
Vector<int32_t> mPointerIds;
Vector<nsecs_t> mSampleEventTimes;
Vector<PointerCoords> mSamplePointerCoords;
-
- inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
- return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
- }
-
- inline const PointerCoords& getHistoricalPointerCoords(
- size_t pointerIndex, size_t historicalIndex) const {
- return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
- }
};
/*
@@ -486,11 +543,11 @@
inline const String8 getName() const { return mName; }
inline uint32_t getSources() const { return mSources; }
- const MotionRange* getMotionRange(int32_t rangeType) const;
+ const MotionRange* getMotionRange(int32_t axis) const;
void addSource(uint32_t source);
- void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
- void addMotionRange(int32_t rangeType, const MotionRange& range);
+ void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
+ void addMotionRange(int32_t axis, const MotionRange& range);
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
inline int32_t getKeyboardType() const { return mKeyboardType; }
diff --git a/include/ui/KeyLayoutMap.h b/include/ui/KeyLayoutMap.h
index f0a6d00..904c8f3 100644
--- a/include/ui/KeyLayoutMap.h
+++ b/include/ui/KeyLayoutMap.h
@@ -25,7 +25,7 @@
namespace android {
/**
- * Describes a mapping from keyboard scan codes to Android key codes.
+ * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
*/
class KeyLayoutMap {
public:
@@ -33,8 +33,10 @@
static status_t load(const String8& filename, KeyLayoutMap** outMap);
- status_t map(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
- status_t findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+ status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
+ status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+
+ status_t mapAxis(int32_t scanCode, int32_t* axis) const;
private:
struct Key {
@@ -42,7 +44,8 @@
uint32_t flags;
};
- KeyedVector<int32_t,Key> mKeys;
+ KeyedVector<int32_t, Key> mKeys;
+ KeyedVector<int32_t, int32_t> mAxes;
KeyLayoutMap();
@@ -57,6 +60,7 @@
private:
status_t parseKey();
+ status_t parseAxis();
};
};
diff --git a/include/ui/Keyboard.h b/include/ui/Keyboard.h
index 50296e2..54bc968 100644
--- a/include/ui/Keyboard.h
+++ b/include/ui/Keyboard.h
@@ -111,6 +111,18 @@
extern uint32_t getKeyFlagByLabel(const char* label);
/**
+ * Gets a axis by its short form label, eg. "X".
+ * Returns -1 if unknown.
+ */
+extern int32_t getAxisByLabel(const char* label);
+
+/**
+ * Gets a axis label by its id.
+ * Returns NULL if unknown.
+ */
+extern const char* getAxisLabel(int32_t axisId);
+
+/**
* Updates a meta state field when a key is pressed or released.
*/
extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index dbccf29..bdfbf7c 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -250,4 +250,47 @@
{ NULL, 0 }
};
+static const KeycodeLabel AXES[] = {
+ { "X", 0 },
+ { "Y", 1 },
+ { "PRESSURE", 2 },
+ { "SIZE", 3 },
+ { "TOUCH_MAJOR", 4 },
+ { "TOUCH_MINOR", 5 },
+ { "TOOL_MAJOR", 6 },
+ { "TOOL_MINOR", 7 },
+ { "ORIENTATION", 8 },
+ { "VSCROLL", 9 },
+ { "HSCROLL", 10 },
+ { "Z", 11 },
+ { "RX", 12 },
+ { "RY", 13 },
+ { "RZ", 14 },
+ { "HAT_X", 15 },
+ { "HAT_Y", 16 },
+ { "LTRIGGER", 17 },
+ { "RTRIGGER", 18 },
+ { "GENERIC_1", 32 },
+ { "GENERIC_2", 33 },
+ { "GENERIC_3", 34 },
+ { "GENERIC_4", 35 },
+ { "GENERIC_5", 36 },
+ { "GENERIC_6", 37 },
+ { "GENERIC_7", 38 },
+ { "GENERIC_8", 39 },
+ { "GENERIC_9", 40 },
+ { "GENERIC_10", 41 },
+ { "GENERIC_11", 42 },
+ { "GENERIC_12", 43 },
+ { "GENERIC_13", 44 },
+ { "GENERIC_14", 45 },
+ { "GENERIC_15", 46 },
+ { "GENERIC_16", 47 },
+
+ // NOTE: If you add a new axis here you must also add it to several other files.
+ // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+
+ { NULL, -1 }
+};
+
#endif // _UI_KEYCODE_LABELS_H
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 624f7eb..9f501e2 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -31,7 +31,7 @@
#include <binder/MemoryHeapBase.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
@@ -108,7 +108,7 @@
{
if (size == 0) {
// try to figure out the size automatically
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
// first try the PMEM ioctl
pmem_region reg;
int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®);
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 16e92f9..03322ea 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -30,7 +30,7 @@
#include <binder/MemoryHeapPmem.h>
#include <binder/MemoryHeapBase.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
@@ -72,7 +72,7 @@
memset(start_ptr, 0xda, size);
#endif
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (size > 0) {
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
@@ -107,7 +107,7 @@
// which means MemoryHeapPmem::revoke() wouldn't have been able to
// promote() it.
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (mSize != 0) {
const sp<MemoryHeapPmem>& heap(getHeap());
int our_fd = heap->heapID();
@@ -130,7 +130,7 @@
: MemoryHeapBase()
{
char const * const device = pmemHeap->getDevice();
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (device) {
int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
@@ -187,7 +187,7 @@
status_t MemoryHeapPmem::slap()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
size_t size = getSize();
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
@@ -205,7 +205,7 @@
status_t MemoryHeapPmem::unslap()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
size_t size = getSize();
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 0042f49..8bae684 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -316,6 +316,8 @@
mTextTexture = NULL;
mIndexBufferID = 0;
+ mPositionAttrSlot = -1;
+ mTexcoordAttrSlot = -1;
mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
mCacheHeight = DEFAULT_TEXT_CACHE_HEIGHT;
@@ -565,13 +567,8 @@
float* vtx = mTextMeshPtr;
float* tex = vtx + 3;
- // position is slot 0
- uint32_t slot = 0;
- glVertexAttribPointer(slot, 3, GL_FLOAT, false, 20, vtx);
-
- // texture0 is slot 1
- slot = 1;
- glVertexAttribPointer(slot, 2, GL_FLOAT, false, 20, tex);
+ glVertexAttribPointer(mPositionAttrSlot, 3, GL_FLOAT, false, 20, vtx);
+ glVertexAttribPointer(mTexcoordAttrSlot, 2, GL_FLOAT, false, 20, tex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);
@@ -718,6 +715,11 @@
return false;
}
+ if (mPositionAttrSlot < 0 || mTexcoordAttrSlot < 0) {
+ LOGE("Font renderer unable to draw, attribute slots undefined");
+ return false;
+ }
+
mDrawn = false;
mBounds = bounds;
mClip = clip;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 1005812..46f332e 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -138,6 +138,11 @@
mGammaTable = gammaTable;
}
+ void setAttributeBindingSlots(int positionSlot, int texCoordSlot) {
+ mPositionAttrSlot = positionSlot;
+ mTexcoordAttrSlot = texCoordSlot;
+ }
+
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
@@ -263,6 +268,9 @@
uint32_t mIndexBufferID;
+ int32_t mPositionAttrSlot;
+ int32_t mTexcoordAttrSlot;
+
const Rect* mClip;
Rect* mBounds;
bool mDrawn;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 68b54fe..4a08f53 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1585,8 +1585,12 @@
#else
bool hasActiveLayer = false;
#endif
-
mCaches.unbindMeshBuffer();
+
+ // Tell font renderer the locations of position and texture coord
+ // attributes so it can bind its data properly
+ int positionSlot = mCaches.currentProgram->position;
+ fontRenderer.setAttributeBindingSlots(positionSlot, mTexCoordsSlot);
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
hasActiveLayer ? &bounds : NULL)) {
#if RENDER_LAYERS_AS_REGIONS
diff --git a/libs/rs/java/Balls/_index.html b/libs/rs/java/Balls/_index.html
new file mode 100644
index 0000000..8760485
--- /dev/null
+++ b/libs/rs/java/Balls/_index.html
@@ -0,0 +1 @@
+<p>A brute force physics simulation that renders many balls onto the screen and moves them according to user touch and gravity.</p>
\ No newline at end of file
diff --git a/libs/rs/java/Fountain/_index.html b/libs/rs/java/Fountain/_index.html
new file mode 100644
index 0000000..223242f
--- /dev/null
+++ b/libs/rs/java/Fountain/_index.html
@@ -0,0 +1,5 @@
+<p>An example that renders many dots on the screen that follow a user's touch. The dots fall
+to the bottom of the screen when the user releases the finger.</p>
+
+
+
diff --git a/libs/rs/java/HelloCompute/_index.html b/libs/rs/java/HelloCompute/_index.html
new file mode 100644
index 0000000..abfd978
--- /dev/null
+++ b/libs/rs/java/HelloCompute/_index.html
@@ -0,0 +1,2 @@
+<p>A Renderscript compute sample that filters a bitmap. No Renderscript graphics APIs are used
+in this sample.</p>
\ No newline at end of file
diff --git a/libs/rs/java/HelloWorld/_index.html b/libs/rs/java/HelloWorld/_index.html
new file mode 100644
index 0000000..4cab738
--- /dev/null
+++ b/libs/rs/java/HelloWorld/_index.html
@@ -0,0 +1 @@
+<p>A Renderscript graphics application that draws the text "Hello, World!" where the user touches.</p>
\ No newline at end of file
diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/libs/rs/java/ImageProcessing/AndroidManifest.xml
index 0fcbf1e..69a33bc 100644
--- a/libs/rs/java/ImageProcessing/AndroidManifest.xml
+++ b/libs/rs/java/ImageProcessing/AndroidManifest.xml
@@ -6,8 +6,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="11" />
<application android:label="Image Processing">
- <activity android:name="ImageProcessingActivity"
- android:screenOrientation="portrait">
+ <activity android:name="ImageProcessingActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/libs/rs/java/ImageProcessing/res/layout/main.xml b/libs/rs/java/ImageProcessing/res/layout/main.xml
index c6ec729..b271b43 100644
--- a/libs/rs/java/ImageProcessing/res/layout/main.xml
+++ b/libs/rs/java/ImageProcessing/res/layout/main.xml
@@ -14,174 +14,140 @@
limitations under the License.
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
<SurfaceView
android:id="@+id/surface"
android:layout_width="1dip"
android:layout_height="1dip" />
-
<ImageView
android:id="@+id/display"
android:layout_width="320dip"
android:layout_height="266dip" />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/benchmark"
+ android:onClick="benchmark"/>
+ <TextView
+ android:id="@+id/benchmarkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:text="@string/saturation"/>
+ </LinearLayout>
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView
+ android:id="@+id/inSaturationText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/saturation"/>
+ <SeekBar
+ android:id="@+id/inSaturation"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inGammaText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/gamma"/>
+ <SeekBar
+ android:id="@+id/inGamma"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/outWhiteText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:textSize="8pt"
+ android:text="@string/out_white"/>
+ <SeekBar
+ android:id="@+id/outWhite"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inWhiteText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_white"/>
+ <SeekBar
+ android:id="@+id/inWhite"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/outBlackText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/out_black"/>
+ <SeekBar
+ android:id="@+id/outBlack"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inBlackText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_black"/>
+ <SeekBar
+ android:id="@+id/inBlack"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/blurText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/blur_description"/>
+ <SeekBar
+ android:id="@+id/radius"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
- <Button
- android:layout_marginBottom="170dip"
- android:layout_width="wrap_content"
- android:layout_height="40dip"
- android:text="@string/benchmark"
- android:onClick="benchmark"
- android:layout_gravity="bottom"/>
-
- <TextView
- android:id="@+id/benchmarkText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="100dip"
- android:layout_marginBottom="175dip"
- android:layout_gravity="bottom"
- android:text="@string/saturation"/>
-
- <SeekBar
- android:id="@+id/inSaturation"
- android:layout_marginBottom="140dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inSaturationText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="142dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/saturation"/>
-
- <SeekBar
- android:id="@+id/inGamma"
- android:layout_marginBottom="110dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inGammaText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="112dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/gamma"/>
-
- <SeekBar
- android:id="@+id/outWhite"
- android:layout_marginBottom="80dip"
- android:layout_marginLeft="170dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/outWhiteText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="220dip"
- android:layout_marginBottom="82dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/out_white"/>
-
- <SeekBar
- android:id="@+id/inWhite"
- android:layout_marginBottom="80dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="170dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inWhiteText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="82dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/in_white"/>
-
- <SeekBar
- android:id="@+id/outBlack"
- android:layout_marginBottom="50dip"
- android:layout_marginLeft="170dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/outBlackText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="220dip"
- android:layout_marginBottom="52dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/out_black"/>
-
- <SeekBar
- android:id="@+id/inBlack"
- android:layout_marginBottom="50dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="170dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inBlackText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="52dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/in_black"/>
-
- <SeekBar
- android:id="@+id/radius"
- android:layout_marginBottom="10dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/blurText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="12dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/blur_description"/>
-
-</merge>
\ No newline at end of file
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 5de09f7..4f2f52ab 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -346,7 +346,7 @@
mSaturationSeekBar.setProgress(50);
mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
- mBenchmarkResult.setText("Benchmark not yet run");
+ mBenchmarkResult.setText("Result: not run");
}
public void surfaceCreated(SurfaceHolder holder) {
@@ -430,7 +430,7 @@
//long javaTime = javaFilter();
//mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms");
- mBenchmarkResult.setText("RS: " + t + " ms");
+ mBenchmarkResult.setText("Result: " + t + " ms");
mRadius = oldRadius;
mScript.set_radius(mRadius);
diff --git a/libs/rs/java/ModelViewer/AndroidManifest.xml b/libs/rs/java/ModelViewer/AndroidManifest.xml
index 959fe53..e5e449b3 100644
--- a/libs/rs/java/ModelViewer/AndroidManifest.xml
+++ b/libs/rs/java/ModelViewer/AndroidManifest.xml
@@ -3,14 +3,19 @@
package="com.android.modelviewer">
<application android:label="ModelViewer">
<activity android:name="SimpleModel"
- android:label="SimpleModel"
- android:screenOrientation="portrait"
- android:theme="@android:style/Theme.Black.NoTitleBar">
+ android:label="SimpleModel">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name="A3DSelector"
+ android:label="A3DSelector"
+ android:hardwareAccelerated="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
<activity android:name="SceneGraph"
android:label="SceneGraph"
android:theme="@android:style/Theme.Black.NoTitleBar">
diff --git a/libs/rs/java/ModelViewer/res/menu/loader_menu.xml b/libs/rs/java/ModelViewer/res/menu/loader_menu.xml
new file mode 100644
index 0000000..3c34023
--- /dev/null
+++ b/libs/rs/java/ModelViewer/res/menu/loader_menu.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/load_model"
+ android:title="@string/load_model" />
+ <item android:id="@+id/display_options"
+ android:title="@string/display_options" />
+</menu>
diff --git a/libs/rs/java/ModelViewer/res/values/strings.xml b/libs/rs/java/ModelViewer/res/values/strings.xml
new file mode 100644
index 0000000..8e1673f
--- /dev/null
+++ b/libs/rs/java/ModelViewer/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <skip />
+ <string name="load_model">Load Model</string>
+ <string name="display_options">Display Options</string>
+</resources>
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java
new file mode 100644
index 0000000..0e2004f
--- /dev/null
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.modelviewer;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * A list view where the last item the user clicked is placed in
+ * the "activated" state, causing its background to highlight.
+ */
+public class A3DSelector extends ListActivity {
+
+ File[] mCurrentSubList;
+ File mCurrentFile;
+
+ class A3DFilter implements FileFilter {
+ public boolean accept(File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
+ return file.getName().endsWith(".a3d");
+ }
+ }
+
+ private void populateList(File file) {
+
+ mCurrentFile = file;
+ setTitle(mCurrentFile.getAbsolutePath() + "/*.a3d");
+ List<String> names = new ArrayList<String>();
+ names.add("..");
+
+ mCurrentSubList = mCurrentFile.listFiles(new A3DFilter());
+
+ if (mCurrentSubList != null) {
+ for (int i = 0; i < mCurrentSubList.length; i ++) {
+ String fileName = mCurrentSubList[i].getName();
+ if (mCurrentSubList[i].isDirectory()) {
+ fileName = "/" + fileName;
+ }
+ names.add(fileName);
+ }
+ }
+
+ // Use the built-in layout for showing a list item with a single
+ // line of text whose background is changes when activated.
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_activated_1, names));
+ getListView().setTextFilterEnabled(true);
+
+ // Tell the list view to show one checked/activated item at a time.
+ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ populateList(new File("/sdcard/"));
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ if (position == 0) {
+ File parent = mCurrentFile.getParentFile();
+ if (parent == null) {
+ return;
+ }
+ populateList(parent);
+ return;
+ }
+
+ // the first thing in list is parent directory
+ File selectedFile = mCurrentSubList[position - 1];
+ if (selectedFile.isDirectory()) {
+ populateList(selectedFile);
+ return;
+ }
+
+ Intent resultIntent = new Intent();
+ resultIntent.setData(Uri.fromFile(selectedFile));
+ setResult(RESULT_OK, resultIntent);
+ finish();
+ }
+
+}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
index 9910970..01cb709 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
@@ -21,6 +21,7 @@
import android.app.Activity;
import android.content.res.Configuration;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -31,9 +32,11 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.MenuInflater;
import android.view.Window;
import android.widget.Button;
import android.widget.ListView;
+import android.net.Uri;
import java.lang.Runtime;
@@ -67,5 +70,45 @@
mView.pause();
}
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.loader_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.load_model:
+ loadModel();
+ return true;
+ case R.id.display_options:
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static final int FIND_A3D_MODEL = 10;
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_OK) {
+ if (requestCode == FIND_A3D_MODEL) {
+ Uri selectedImageUri = data.getData();
+ Log.e("Selected Path: ", selectedImageUri.getPath());
+ mView.loadA3DFile(selectedImageUri.getPath());
+ }
+ }
+ }
+
+ public void loadModel() {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_PICK);
+ intent.setClassName("com.android.modelviewer",
+ "com.android.modelviewer.A3DSelector");
+ startActivityForResult(intent, FIND_A3D_MODEL);
+ }
+
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index b18a327..63ef466 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,24 +26,20 @@
public class SimpleModelRS {
- private final int STATE_LAST_FOCUS = 1;
-
- int mWidth;
- int mHeight;
- int mRotation;
-
public SimpleModelRS() {
}
- public void init(RenderScriptGL rs, Resources res, int width, int height) {
+ public void init(RenderScriptGL rs, Resources res) {
mRS = rs;
mRes = res;
- mWidth = width;
- mHeight = height;
- mRotation = 0;
initRS();
}
+ public void surfaceChanged() {
+ mRS.getWidth();
+ mRS.getHeight();
+ }
+
private Resources mRes;
private RenderScriptGL mRS;
private Sampler mSampler;
@@ -55,34 +51,23 @@
private Allocation mGridImage;
private Allocation mAllocPV;
- private Mesh mMesh;
-
private Font mItalic;
private Allocation mTextAlloc;
+ private ScriptField_MeshInfo mMeshes;
private ScriptC_simplemodel mScript;
- int mLastX;
- int mLastY;
- public void touchEvent(int x, int y) {
- int dx = mLastX - x;
- if (Math.abs(dx) > 50 || Math.abs(dx) < 3) {
- dx = 0;
- }
+ public void onActionDown(float x, float y) {
+ mScript.invoke_onActionDown(x, y);
+ }
- mRotation -= dx;
- if (mRotation > 360) {
- mRotation -= 360;
- }
- if (mRotation < 0) {
- mRotation += 360;
- }
+ public void onActionScale(float scale) {
+ mScript.invoke_onActionScale(scale);
+ }
- mScript.set_gRotate((float)mRotation);
-
- mLastX = x;
- mLastY = y;
+ public void onActionMove(float x, float y) {
+ mScript.invoke_onActionMove(x, y);
}
private void initPFS() {
@@ -130,12 +115,48 @@
mScript.set_gTGrid(mGridImage);
}
- private void initTextAllocation() {
- String allocString = "Displaying file: R.raw.robot";
+ private void initTextAllocation(String fileName) {
+ String allocString = "Displaying file: " + fileName;
mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
mScript.set_gTextAlloc(mTextAlloc);
}
+ private void initMeshes(FileA3D model) {
+ int numEntries = model.getIndexEntryCount();
+ int numMeshes = 0;
+ for (int i = 0; i < numEntries; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ numMeshes ++;
+ }
+ }
+
+ if (numMeshes > 0) {
+ mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
+
+ for (int i = 0; i < numEntries; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ Mesh mesh = entry.getMesh();
+ mMeshes.set_mMesh(i, mesh, false);
+ mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
+ }
+ }
+ mMeshes.copyAll();
+ } else {
+ throw new RSRuntimeException("No valid meshes in file");
+ }
+
+ mScript.bind_gMeshes(mMeshes);
+ mScript.invoke_updateMeshInfo();
+ }
+
+ public void loadA3DFile(String path) {
+ FileA3D model = FileA3D.createFromFile(mRS, path);
+ initMeshes(model);
+ initTextAllocation(path);
+ }
+
private void initRS() {
mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel);
@@ -147,18 +168,12 @@
loadImage();
FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
- FileA3D.IndexEntry entry = model.getIndexEntry(0);
- if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
- Log.e("rs", "could not load model");
- } else {
- mMesh = (Mesh)entry.getObject();
- mScript.set_gTestMesh(mMesh);
- }
+ initMeshes(model);
mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
mScript.set_gItalic(mItalic);
- initTextAllocation();
+ initTextAllocation("R.raw.robot");
mRS.bindRootScript(mScript);
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
index 5c5956d..9ab0f22 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,81 +16,129 @@
package com.android.modelviewer;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
import android.renderscript.RSSurfaceView;
-import android.renderscript.RenderScript;
import android.renderscript.RenderScriptGL;
import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.ScaleGestureDetector;
+import android.util.Log;
public class SimpleModelView extends RSSurfaceView {
- public SimpleModelView(Context context) {
- super(context);
- //setFocusable(true);
- }
-
private RenderScriptGL mRS;
private SimpleModelRS mRender;
+ private ScaleGestureDetector mScaleDetector;
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
- super.surfaceChanged(holder, format, w, h);
+ private static final int INVALID_POINTER_ID = -1;
+ private int mActivePointerId = INVALID_POINTER_ID;
+
+ public SimpleModelView(Context context) {
+ super(context);
+ ensureRenderScript();
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ }
+
+ private void ensureRenderScript() {
if (mRS == null) {
RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
sc.setDepth(16, 24);
mRS = createRenderScriptGL(sc);
- mRS.setSurface(holder, w, h);
mRender = new SimpleModelRS();
- mRender.init(mRS, getResources(), w, h);
+ mRender.init(mRS, getResources());
}
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ ensureRenderScript();
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ mRender.surfaceChanged();
+ }
+
+ @Override
protected void onDetachedFromWindow() {
+ mRender = null;
if (mRS != null) {
mRS = null;
destroyRenderScriptGL();
}
}
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- // break point at here
- // this method doesn't work when 'extends View' include 'extends ScrollView'.
- return super.onKeyDown(keyCode, event);
+ public void loadA3DFile(String path) {
+ mRender.loadA3DFile(path);
}
-
@Override
- public boolean onTouchEvent(MotionEvent ev)
- {
- boolean ret = true;
- int act = ev.getAction();
- if (act == ev.ACTION_UP) {
- ret = false;
+ public boolean onTouchEvent(MotionEvent ev) {
+ mScaleDetector.onTouchEvent(ev);
+
+ boolean ret = false;
+ float x = ev.getX();
+ float y = ev.getY();
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(0);
+ ret = true;
+ break;
+ }
+ case MotionEvent.ACTION_MOVE: {
+ if (!mScaleDetector.isInProgress()) {
+ mRender.onActionMove(x, y);
+ }
+ mRender.onActionDown(x, y);
+ ret = true;
+ break;
}
- mRender.touchEvent((int)ev.getX(), (int)ev.getY());
+ case MotionEvent.ACTION_UP: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ x = ev.getX(newPointerIndex);
+ y = ev.getY(newPointerIndex);
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ }
+ break;
+ }
+ }
+
return ret;
}
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ mRender.onActionScale(detector.getScaleFactor());
+ return true;
+ }
+ }
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index 419de62..1034b85 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 The Android Open Source Project
+// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,17 +22,112 @@
rs_program_fragment gPFBackground;
rs_allocation gTGrid;
-rs_mesh gTestMesh;
rs_program_store gPFSBackground;
-float gRotate;
-
rs_font gItalic;
rs_allocation gTextAlloc;
+typedef struct MeshInfo {
+ rs_mesh mMesh;
+ int mNumIndexSets;
+ float3 bBoxMin;
+ float3 bBoxMax;
+} MeshInfo_t;
+
+MeshInfo_t *gMeshes;
+
+static float3 gLookAt;
+
+static float gRotateX;
+static float gRotateY;
+static float gZoom;
+
+static float gLastX;
+static float gLastY;
+
+void onActionDown(float x, float y) {
+ gLastX = x;
+ gLastY = y;
+}
+
+void onActionScale(float scale) {
+
+ gZoom *= 1.0f / scale;
+ gZoom = max(0.1f, min(gZoom, 500.0f));
+}
+
+void onActionMove(float x, float y) {
+ float dx = gLastX - x;
+ float dy = gLastY - y;
+
+ if (fabs(dy) <= 2.0f) {
+ dy = 0.0f;
+ }
+ if (fabs(dx) <= 2.0f) {
+ dx = 0.0f;
+ }
+
+ gRotateY -= dx;
+ if (gRotateY > 360) {
+ gRotateY -= 360;
+ }
+ if (gRotateY < 0) {
+ gRotateY += 360;
+ }
+
+ gRotateX -= dy;
+ gRotateX = min(gRotateX, 80.0f);
+ gRotateX = max(gRotateX, -80.0f);
+
+ gLastX = x;
+ gLastY = y;
+}
+
void init() {
- gRotate = 0.0f;
+ gRotateX = 0.0f;
+ gRotateY = 0.0f;
+ gZoom = 50.0f;
+ gLookAt = 0.0f;
+}
+
+void updateMeshInfo() {
+ rs_allocation allMeshes = rsGetAllocation(gMeshes);
+ int size = rsAllocationGetDimX(allMeshes);
+ gLookAt = 0.0f;
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ for (int i = 0; i < size; i++) {
+ MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+ rsgMeshComputeBoundingBox(info->mMesh,
+ &minX, &minY, &minZ,
+ &maxX, &maxY, &maxZ);
+ info->bBoxMin = (minX, minY, minZ);
+ info->bBoxMax = (maxX, maxY, maxZ);
+ gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
+ }
+ gLookAt = gLookAt / (float)size;
+}
+
+static void renderAllMeshes() {
+ rs_allocation allMeshes = rsGetAllocation(gMeshes);
+ int size = rsAllocationGetDimX(allMeshes);
+ gLookAt = 0.0f;
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ for (int i = 0; i < size; i++) {
+ MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+ rsgDrawMesh(info->mMesh);
+ }
+}
+
+void drawDescription() {
+ uint width = rsgGetWidth();
+ uint height = rsgGetHeight();
+ int left = 0, right = 0, top = 0, bottom = 0;
+
+ rsgBindFont(gItalic);
+
+ rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
+ rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom);
}
int root(int launchID) {
@@ -43,7 +138,7 @@
rsgBindProgramVertex(gPVBackground);
rs_matrix4x4 proj;
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
- rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
rsgProgramVertexLoadProjectionMatrix(&proj);
rsgBindProgramFragment(gPFBackground);
@@ -52,20 +147,15 @@
rs_matrix4x4 matrix;
rsMatrixLoadIdentity(&matrix);
- // Position our model on the screen
- rsMatrixTranslate(&matrix, 0.0f, -0.3f, -10.0f);
- rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
- rsMatrixRotate(&matrix, 25.0f, 1.0f, 0.0f, 0.0f);
- rsMatrixRotate(&matrix, gRotate, 0.0f, 1.0f, 0.0f);
+ // Position our models on the screen
+ rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
+ rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
+ rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
rsgProgramVertexLoadModelMatrix(&matrix);
- rsgDrawMesh(gTestMesh);
+ renderAllMeshes();
- rsgFontColor(0.3f, 0.3f, 0.3f, 1.0f);
- rsgDrawText("Renderscript model test", 30, 695);
-
- rsgBindFont(gItalic);
- rsgDrawText(gTextAlloc, 30, 730);
+ drawDescription();
return 10;
}
diff --git a/libs/rs/java/Samples/_index.html b/libs/rs/java/Samples/_index.html
new file mode 100644
index 0000000..5872431
--- /dev/null
+++ b/libs/rs/java/Samples/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/libs/rs/java/_index.html b/libs/rs/java/_index.html
new file mode 100644
index 0000000..5872431
--- /dev/null
+++ b/libs/rs/java/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p>
\ No newline at end of file
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
index 2cc1f8e..7730eb1 100644
--- a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
@@ -157,7 +157,7 @@
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
+ if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
// we're called from a different process, do the real check
if (!checkCallingPermission(
String16("android.permission.ACCESS_SURFACE_FLINGER")))
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 0d55f08..f9990bb 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -60,7 +60,12 @@
libEGL \
libpixelflinger \
libhardware \
- libhardware_legacy
+ libhardware_legacy \
+ libskia \
+ libbinder
+
+LOCAL_C_INCLUDES := \
+ external/skia/include/core
LOCAL_MODULE:= libui
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index b8d59e6..a80320e 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -15,6 +15,16 @@
#include <ui/Input.h>
+#include <math.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <binder/Parcel.h>
+
+#include "SkPoint.h"
+#include "SkMatrix.h"
+#include "SkScalar.h"
+#endif
+
namespace android {
static const char* CONFIGURATION_FILE_DIR[] = {
@@ -237,6 +247,89 @@
mEventTime = from.mEventTime;
}
+
+// --- PointerCoords ---
+
+float PointerCoords::getAxisValue(int32_t axis) const {
+ if (axis < 0 || axis > 63) {
+ return 0;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ if (!(bits & axisBit)) {
+ return 0;
+ }
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ return values[index];
+}
+
+status_t PointerCoords::setAxisValue(int32_t axis, float value) {
+ if (axis < 0 || axis > 63) {
+ return NAME_NOT_FOUND;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ if (!(bits & axisBit)) {
+ uint32_t count = __builtin_popcountll(bits);
+ if (count >= MAX_AXES) {
+ tooManyAxes(axis);
+ return NO_MEMORY;
+ }
+ bits |= axisBit;
+ for (uint32_t i = count; i > index; i--) {
+ values[i] = values[i - 1];
+ }
+ }
+ values[index] = value;
+ return OK;
+}
+
+float* PointerCoords::editAxisValue(int32_t axis) {
+ if (axis < 0 || axis > 63) {
+ return NULL;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ if (!(bits & axisBit)) {
+ return NULL;
+ }
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ return &values[index];
+}
+
+#ifdef HAVE_ANDROID_OS
+status_t PointerCoords::readFromParcel(Parcel* parcel) {
+ bits = parcel->readInt64();
+
+ uint32_t count = __builtin_popcountll(bits);
+ if (count > MAX_AXES) {
+ return BAD_VALUE;
+ }
+
+ for (uint32_t i = 0; i < count; i++) {
+ values[i] = parcel->readInt32();
+ }
+ return OK;
+}
+
+status_t PointerCoords::writeToParcel(Parcel* parcel) const {
+ parcel->writeInt64(bits);
+
+ uint32_t count = __builtin_popcountll(bits);
+ for (uint32_t i = 0; i < count; i++) {
+ parcel->writeInt32(values[i]);
+ }
+ return OK;
+}
+#endif
+
+void PointerCoords::tooManyAxes(int axis) {
+ LOGW("Could not set value for axis %d because the PointerCoords structure is full and "
+ "cannot contain more than %d axis values.", axis, int(MAX_AXES));
+}
+
+
// --- MotionEvent ---
void MotionEvent::initialize(
@@ -272,6 +365,33 @@
addSample(eventTime, pointerCoords);
}
+void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
+ InputEvent::initialize(other->mDeviceId, other->mSource);
+ mAction = other->mAction;
+ mFlags = other->mFlags;
+ mEdgeFlags = other->mEdgeFlags;
+ mMetaState = other->mMetaState;
+ mXOffset = other->mXOffset;
+ mYOffset = other->mYOffset;
+ mXPrecision = other->mXPrecision;
+ mYPrecision = other->mYPrecision;
+ mDownTime = other->mDownTime;
+ mPointerIds = other->mPointerIds;
+
+ if (keepHistory) {
+ mSampleEventTimes = other->mSampleEventTimes;
+ mSamplePointerCoords = other->mSamplePointerCoords;
+ } else {
+ mSampleEventTimes.clear();
+ mSampleEventTimes.push(other->getEventTime());
+ mSamplePointerCoords.clear();
+ size_t pointerCount = other->getPointerCount();
+ size_t historySize = other->getHistorySize();
+ mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
+ + (historySize * pointerCount), pointerCount);
+ }
+}
+
void MotionEvent::addSample(
int64_t eventTime,
const PointerCoords* pointerCoords) {
@@ -279,11 +399,224 @@
mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
}
+const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
+ return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
+ return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
+ float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
+ switch (axis) {
+ case AMOTION_EVENT_AXIS_X:
+ value += mXOffset;
+ break;
+ case AMOTION_EVENT_AXIS_Y:
+ value += mYOffset;
+ break;
+ }
+ return value;
+}
+
+const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
+ size_t pointerIndex, size_t historicalIndex) const {
+ return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+}
+
+float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
+ size_t historicalIndex) const {
+ return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+}
+
+float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
+ size_t historicalIndex) const {
+ float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
+ switch (axis) {
+ case AMOTION_EVENT_AXIS_X:
+ value += mXOffset;
+ break;
+ case AMOTION_EVENT_AXIS_Y:
+ value += mYOffset;
+ break;
+ }
+ return value;
+}
+
void MotionEvent::offsetLocation(float xOffset, float yOffset) {
mXOffset += xOffset;
mYOffset += yOffset;
}
+static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
+ float* value = c.editAxisValue(axis);
+ if (value) {
+ *value *= scaleFactor;
+ }
+}
+
+void MotionEvent::scale(float scaleFactor) {
+ mXOffset *= scaleFactor;
+ mYOffset *= scaleFactor;
+ mXPrecision *= scaleFactor;
+ mYPrecision *= scaleFactor;
+
+ size_t numSamples = mSamplePointerCoords.size();
+ for (size_t i = 0; i < numSamples; i++) {
+ PointerCoords& c = mSamplePointerCoords.editItemAt(i);
+ // No need to scale pressure or size since they are normalized.
+ // No need to scale orientation since it is meaningless to do so.
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_X, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_Y, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
+ }
+}
+
+#ifdef HAVE_ANDROID_OS
+static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
+ // Construct and transform a vector oriented at the specified clockwise angle from vertical.
+ // Coordinate system: down is increasing Y, right is increasing X.
+ SkPoint vector;
+ vector.fX = SkFloatToScalar(sinf(angleRadians));
+ vector.fY = SkFloatToScalar(-cosf(angleRadians));
+ matrix->mapVectors(& vector, 1);
+
+ // Derive the transformed vector's clockwise angle from vertical.
+ float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
+ if (result < - M_PI_2) {
+ result += M_PI;
+ } else if (result > M_PI_2) {
+ result -= M_PI;
+ }
+ return result;
+}
+
+void MotionEvent::transform(const SkMatrix* matrix) {
+ float oldXOffset = mXOffset;
+ float oldYOffset = mYOffset;
+
+ // The tricky part of this implementation is to preserve the value of
+ // rawX and rawY. So we apply the transformation to the first point
+ // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
+ SkPoint point;
+ float rawX = getRawX(0);
+ float rawY = getRawY(0);
+ matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
+ & point);
+ float newX = SkScalarToFloat(point.fX);
+ float newY = SkScalarToFloat(point.fY);
+ float newXOffset = newX - rawX;
+ float newYOffset = newY - rawY;
+
+ mXOffset = newXOffset;
+ mYOffset = newYOffset;
+
+ // Apply the transformation to all samples.
+ size_t numSamples = mSamplePointerCoords.size();
+ for (size_t i = 0; i < numSamples; i++) {
+ PointerCoords& c = mSamplePointerCoords.editItemAt(i);
+ float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
+ float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
+ if (xPtr && yPtr) {
+ float x = *xPtr + oldXOffset;
+ float y = *yPtr + oldYOffset;
+ matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
+ *xPtr = SkScalarToFloat(point.fX) - newXOffset;
+ *yPtr = SkScalarToFloat(point.fY) - newYOffset;
+ }
+
+ float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+ if (orientationPtr) {
+ *orientationPtr = transformAngle(matrix, *orientationPtr);
+ }
+ }
+}
+
+status_t MotionEvent::readFromParcel(Parcel* parcel) {
+ size_t pointerCount = parcel->readInt32();
+ size_t sampleCount = parcel->readInt32();
+ if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
+ return BAD_VALUE;
+ }
+
+ mDeviceId = parcel->readInt32();
+ mSource = parcel->readInt32();
+ mAction = parcel->readInt32();
+ mFlags = parcel->readInt32();
+ mEdgeFlags = parcel->readInt32();
+ mMetaState = parcel->readInt32();
+ mXOffset = parcel->readFloat();
+ mYOffset = parcel->readFloat();
+ mXPrecision = parcel->readFloat();
+ mYPrecision = parcel->readFloat();
+ mDownTime = parcel->readInt64();
+
+ mPointerIds.clear();
+ mPointerIds.setCapacity(pointerCount);
+ mSampleEventTimes.clear();
+ mSampleEventTimes.setCapacity(sampleCount);
+ mSamplePointerCoords.clear();
+ mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
+
+ for (size_t i = 0; i < pointerCount; i++) {
+ mPointerIds.push(parcel->readInt32());
+ }
+
+ while (sampleCount-- > 0) {
+ mSampleEventTimes.push(parcel->readInt64());
+ for (size_t i = 0; i < pointerCount; i++) {
+ mSamplePointerCoords.push();
+ status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
+ if (status) {
+ return status;
+ }
+ }
+ }
+ return OK;
+}
+
+status_t MotionEvent::writeToParcel(Parcel* parcel) const {
+ size_t pointerCount = mPointerIds.size();
+ size_t sampleCount = mSampleEventTimes.size();
+
+ parcel->writeInt32(pointerCount);
+ parcel->writeInt32(sampleCount);
+
+ parcel->writeInt32(mDeviceId);
+ parcel->writeInt32(mSource);
+ parcel->writeInt32(mAction);
+ parcel->writeInt32(mFlags);
+ parcel->writeInt32(mEdgeFlags);
+ parcel->writeInt32(mMetaState);
+ parcel->writeFloat(mXOffset);
+ parcel->writeFloat(mYOffset);
+ parcel->writeFloat(mXPrecision);
+ parcel->writeFloat(mYPrecision);
+ parcel->writeInt64(mDownTime);
+
+ for (size_t i = 0; i < pointerCount; i++) {
+ parcel->writeInt32(mPointerIds.itemAt(i));
+ }
+
+ const PointerCoords* pc = mSamplePointerCoords.array();
+ for (size_t h = 0; h < sampleCount; h++) {
+ parcel->writeInt64(mSampleEventTimes.itemAt(h));
+ for (size_t i = 0; i < pointerCount; i++) {
+ status_t status = (pc++)->writeToParcel(parcel);
+ if (status) {
+ return status;
+ }
+ }
+ }
+ return OK;
+}
+#endif
+
+
// --- InputDeviceInfo ---
InputDeviceInfo::InputDeviceInfo() {
@@ -307,8 +640,8 @@
mMotionRanges.clear();
}
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t rangeType) const {
- ssize_t index = mMotionRanges.indexOfKey(rangeType);
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
+ ssize_t index = mMotionRanges.indexOfKey(axis);
return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
}
@@ -316,14 +649,14 @@
mSources |= source;
}
-void InputDeviceInfo::addMotionRange(int32_t rangeType, float min, float max,
+void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
float flat, float fuzz) {
MotionRange range = { min, max, flat, fuzz };
- addMotionRange(rangeType, range);
+ addMotionRange(axis, range);
}
-void InputDeviceInfo::addMotionRange(int32_t rangeType, const MotionRange& range) {
- mMotionRanges.add(rangeType, range);
+void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
+ mMotionRanges.add(axis, range);
}
} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 83d9556..5c57a76 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -412,7 +412,8 @@
// Cache essential information about the motion event to ensure that a malicious consumer
// cannot confuse the publisher by modifying the contents of the shared memory buffer while
// it is being updated.
- if (action == AMOTION_EVENT_ACTION_MOVE) {
+ if (action == AMOTION_EVENT_ACTION_MOVE
+ || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
mMotionEventPointerCount = pointerCount;
mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount);
mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement(
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
index 56bc26f..2ed0e66 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -82,11 +82,11 @@
return status;
}
-status_t KeyLayoutMap::map(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
+status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
ssize_t index = mKeys.indexOfKey(scanCode);
if (index < 0) {
#if DEBUG_MAPPING
- LOGD("map: scanCode=%d ~ Failed.", scanCode);
+ LOGD("mapKey: scanCode=%d ~ Failed.", scanCode);
#endif
*keyCode = AKEYCODE_UNKNOWN;
*flags = 0;
@@ -98,12 +98,12 @@
*flags = k.flags;
#if DEBUG_MAPPING
- LOGD("map: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
+ LOGD("mapKey: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
#endif
return NO_ERROR;
}
-status_t KeyLayoutMap::findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
+status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
const size_t N = mKeys.size();
for (size_t i=0; i<N; i++) {
if (mKeys.valueAt(i).keyCode == keyCode) {
@@ -113,6 +113,25 @@
return NO_ERROR;
}
+status_t KeyLayoutMap::mapAxis(int32_t scanCode, int32_t* axis) const {
+ ssize_t index = mAxes.indexOfKey(scanCode);
+ if (index < 0) {
+#if DEBUG_MAPPING
+ LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
+#endif
+ *axis = -1;
+ return NAME_NOT_FOUND;
+ }
+
+ *axis = mAxes.valueAt(index);
+
+#if DEBUG_MAPPING
+ LOGD("mapAxis: scanCode=%d ~ Result axis=%d.", scanCode, *axis);
+#endif
+ return NO_ERROR;
+}
+
+
// --- KeyLayoutMap::Parser ---
KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
@@ -137,6 +156,10 @@
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseKey();
if (status) return status;
+ } else if (keywordToken == "axis") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ status_t status = parseAxis();
+ if (status) return status;
} else {
LOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
keywordToken.string());
@@ -162,12 +185,12 @@
char* end;
int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
if (*end) {
- LOGE("%s: Expected scan code number, got '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
}
if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
- LOGE("%s: Duplicate entry for scan code '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
}
@@ -189,12 +212,12 @@
String8 flagToken = mTokenizer->nextToken(WHITESPACE);
uint32_t flag = getKeyFlagByLabel(flagToken.string());
if (!flag) {
- LOGE("%s: Expected flag label, got '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
if (flags & flag) {
- LOGE("%s: Duplicate flag '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
@@ -211,4 +234,35 @@
return NO_ERROR;
}
+status_t KeyLayoutMap::Parser::parseAxis() {
+ String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+ char* end;
+ int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+ if (*end) {
+ LOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
+ scanCodeToken.string());
+ return BAD_VALUE;
+ }
+ if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
+ LOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
+ scanCodeToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 axisToken = mTokenizer->nextToken(WHITESPACE);
+ int32_t axis = getAxisByLabel(axisToken.string());
+ if (axis < 0) {
+ LOGE("%s: Expected axis label, got '%s'.", mTokenizer->getLocation().string(),
+ axisToken.string());
+ return BAD_VALUE;
+ }
+
+#if DEBUG_PARSER
+ LOGD("Parsed axis: scanCode=%d, axis=%d.", scanCode, axis);
+#endif
+ mMap->mAxes.add(scanCode, axis);
+ return NO_ERROR;
+}
+
};
diff --git a/libs/ui/Keyboard.cpp b/libs/ui/Keyboard.cpp
index 6faa600..8b6300a 100644
--- a/libs/ui/Keyboard.cpp
+++ b/libs/ui/Keyboard.cpp
@@ -217,7 +217,7 @@
return NAME_NOT_FOUND;
}
-static int lookupLabel(const char* literal, const KeycodeLabel *list) {
+static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
while (list->literal) {
if (strcmp(literal, list->literal) == 0) {
return list->value;
@@ -227,12 +227,30 @@
return list->value;
}
+static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
+ while (list->literal) {
+ if (list->value == value) {
+ return list->literal;
+ }
+ list++;
+ }
+ return NULL;
+}
+
int32_t getKeyCodeByLabel(const char* label) {
- return int32_t(lookupLabel(label, KEYCODES));
+ return int32_t(lookupValueByLabel(label, KEYCODES));
}
uint32_t getKeyFlagByLabel(const char* label) {
- return uint32_t(lookupLabel(label, FLAGS));
+ return uint32_t(lookupValueByLabel(label, FLAGS));
+}
+
+int32_t getAxisByLabel(const char* label) {
+ return int32_t(lookupValueByLabel(label, AXES));
+}
+
+const char* getAxisLabel(int32_t axisId) {
+ return lookupLabelByValue(axisId, AXES);
}
static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 580d73c..e231971 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -7,6 +7,7 @@
# Build the unit tests.
test_src_files := \
InputChannel_test.cpp \
+ InputEvent_test.cpp \
InputPublisherAndConsumer_test.cpp
shared_libraries := \
@@ -18,7 +19,8 @@
libhardware \
libhardware_legacy \
libui \
- libstlport
+ libstlport \
+ libskia
static_libraries := \
libgtest \
@@ -28,7 +30,8 @@
bionic \
bionic/libstdc++/include \
external/gtest/include \
- external/stlport/stlport
+ external/stlport/stlport \
+ external/skia/include/core
module_tags := eng tests
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
index 6cec1c02..eff22ee 100644
--- a/libs/ui/tests/InputChannel_test.cpp
+++ b/libs/ui/tests/InputChannel_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include <ui/InputTransport.h>
#include <utils/Timers.h>
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
new file mode 100644
index 0000000..b77489e
--- /dev/null
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ui/Input.h>
+#include <gtest/gtest.h>
+#include <binder/Parcel.h>
+
+#include <math.h>
+#include <SkMatrix.h>
+
+namespace android {
+
+class BaseTest : public testing::Test {
+protected:
+ virtual void SetUp() { }
+ virtual void TearDown() { }
+};
+
+// --- PointerCoordsTest ---
+
+class PointerCoordsTest : public BaseTest {
+};
+
+TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
+ PointerCoords coords;
+ coords.clear();
+
+ ASSERT_EQ(0ULL, coords.bits);
+}
+
+TEST_F(PointerCoordsTest, AxisValues) {
+ float* valuePtr;
+ PointerCoords coords;
+ coords.clear();
+
+ // Check invariants when no axes are present.
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(0, coords.getAxisValue(1))
+ << "getAxisValue should return zero because axis is not present";
+
+ ASSERT_EQ(NULL, coords.editAxisValue(0))
+ << "editAxisValue should return null because axis is not present";
+
+ // Set first axis.
+ ASSERT_EQ(OK, coords.setAxisValue(1, 5));
+ ASSERT_EQ(0x00000002ULL, coords.bits);
+ ASSERT_EQ(5, coords.values[0]);
+
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with a higher id than all others. (appending value at the end)
+ ASSERT_EQ(OK, coords.setAxisValue(3, 2));
+ ASSERT_EQ(0x0000000aULL, coords.bits);
+ ASSERT_EQ(5, coords.values[0]);
+ ASSERT_EQ(2, coords.values[1]);
+
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(0, coords.getAxisValue(2))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with an id lower than all others. (prepending value at beginning)
+ ASSERT_EQ(OK, coords.setAxisValue(0, 4));
+ ASSERT_EQ(0x0000000bULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(5, coords.values[1]);
+ ASSERT_EQ(2, coords.values[2]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(0, coords.getAxisValue(2))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Edit an existing axis value in place.
+ valuePtr = coords.editAxisValue(1);
+ ASSERT_EQ(5, *valuePtr)
+ << "editAxisValue should return pointer to axis value";
+
+ *valuePtr = 7;
+ ASSERT_EQ(7, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with an id between the others. (inserting value in the middle)
+ ASSERT_EQ(OK, coords.setAxisValue(2, 1));
+ ASSERT_EQ(0x0000000fULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(7, coords.values[1]);
+ ASSERT_EQ(1, coords.values[2]);
+ ASSERT_EQ(2, coords.values[3]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(7, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(1, coords.getAxisValue(2))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set an existing axis value in place.
+ ASSERT_EQ(OK, coords.setAxisValue(1, 6));
+ ASSERT_EQ(0x0000000fULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(6, coords.values[1]);
+ ASSERT_EQ(1, coords.values[2]);
+ ASSERT_EQ(2, coords.values[3]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(6, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(1, coords.getAxisValue(2))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set maximum number of axes.
+ for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
+ ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
+ }
+ ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+
+ // Try to set one more axis beyond maximum number.
+ // Ensure bits are unchanged.
+ ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
+ ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+}
+
+TEST_F(PointerCoordsTest, Parcel) {
+ Parcel parcel;
+
+ PointerCoords inCoords;
+ inCoords.clear();
+ PointerCoords outCoords;
+
+ // Round trip with empty coords.
+ inCoords.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outCoords.readFromParcel(&parcel);
+
+ ASSERT_EQ(0ULL, outCoords.bits);
+
+ // Round trip with some values.
+ parcel.freeData();
+ inCoords.setAxisValue(2, 5);
+ inCoords.setAxisValue(5, 8);
+
+ inCoords.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outCoords.readFromParcel(&parcel);
+
+ ASSERT_EQ(outCoords.bits, inCoords.bits);
+ ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
+ ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
+}
+
+
+// --- KeyEventTest ---
+
+class KeyEventTest : public BaseTest {
+};
+
+TEST_F(KeyEventTest, Properties) {
+ KeyEvent event;
+
+ // Initialize and get properties.
+ const nsecs_t ARBITRARY_DOWN_TIME = 1;
+ const nsecs_t ARBITRARY_EVENT_TIME = 2;
+ event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
+ AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
+ AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
+
+ ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
+ ASSERT_EQ(2, event.getDeviceId());
+ ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
+ ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
+ ASSERT_EQ(121, event.getScanCode());
+ ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
+ ASSERT_EQ(1, event.getRepeatCount());
+ ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
+ ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
+
+ // Set source.
+ event.setSource(AINPUT_SOURCE_JOYSTICK);
+ ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+}
+
+
+// --- MotionEventTest ---
+
+class MotionEventTest : public BaseTest {
+protected:
+ static const nsecs_t ARBITRARY_DOWN_TIME;
+ static const nsecs_t ARBITRARY_EVENT_TIME;
+ static const float X_OFFSET;
+ static const float Y_OFFSET;
+
+ void initializeEventWithHistory(MotionEvent* event);
+ void assertEqualsEventWithHistory(const MotionEvent* event);
+};
+
+const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
+const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
+const float MotionEventTest::X_OFFSET = 1.0f;
+const float MotionEventTest::Y_OFFSET = 1.1f;
+
+void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
+ int32_t pointerIds[] = { 1, 2 };
+ PointerCoords pointerCoords[2];
+ pointerCoords[0].clear();
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
+ pointerCoords[1].clear();
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
+ event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
+ AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
+ AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON,
+ X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
+ ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
+ 2, pointerIds, pointerCoords);
+
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
+ event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
+
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
+ event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
+}
+
+void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
+ // Check properties.
+ ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
+ ASSERT_EQ(2, event->getDeviceId());
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
+ ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
+ ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
+ ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
+ ASSERT_EQ(X_OFFSET, event->getXOffset());
+ ASSERT_EQ(Y_OFFSET, event->getYOffset());
+ ASSERT_EQ(2.0f, event->getXPrecision());
+ ASSERT_EQ(2.1f, event->getYPrecision());
+ ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
+
+ ASSERT_EQ(2U, event->getPointerCount());
+ ASSERT_EQ(1, event->getPointerId(0));
+ ASSERT_EQ(2, event->getPointerId(1));
+
+ ASSERT_EQ(2U, event->getHistorySize());
+
+ // Check data.
+ ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
+ ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
+ ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
+
+ ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(211, event->getRawPointerCoords(0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(221, event->getRawPointerCoords(1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+
+ ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
+ ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
+ ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
+ ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
+ ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
+ ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
+
+ ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
+ ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
+ ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
+ ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
+ ASSERT_EQ(210, event->getRawX(0));
+ ASSERT_EQ(220, event->getRawX(1));
+
+ ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
+ ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
+ ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
+ ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
+ ASSERT_EQ(211, event->getRawY(0));
+ ASSERT_EQ(221, event->getRawY(1));
+
+ ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
+ ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
+ ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
+ ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
+ ASSERT_EQ(X_OFFSET + 210, event->getX(0));
+ ASSERT_EQ(X_OFFSET + 220, event->getX(1));
+
+ ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
+ ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
+ ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
+ ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
+ ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
+ ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
+
+ ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
+ ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
+ ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
+ ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
+ ASSERT_EQ(212, event->getPressure(0));
+ ASSERT_EQ(222, event->getPressure(1));
+
+ ASSERT_EQ(13, event->getHistoricalSize(0, 0));
+ ASSERT_EQ(23, event->getHistoricalSize(1, 0));
+ ASSERT_EQ(113, event->getHistoricalSize(0, 1));
+ ASSERT_EQ(123, event->getHistoricalSize(1, 1));
+ ASSERT_EQ(213, event->getSize(0));
+ ASSERT_EQ(223, event->getSize(1));
+
+ ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
+ ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
+ ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
+ ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
+ ASSERT_EQ(214, event->getTouchMajor(0));
+ ASSERT_EQ(224, event->getTouchMajor(1));
+
+ ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
+ ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
+ ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
+ ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
+ ASSERT_EQ(215, event->getTouchMinor(0));
+ ASSERT_EQ(225, event->getTouchMinor(1));
+
+ ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
+ ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
+ ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
+ ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
+ ASSERT_EQ(216, event->getToolMajor(0));
+ ASSERT_EQ(226, event->getToolMajor(1));
+
+ ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
+ ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
+ ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
+ ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
+ ASSERT_EQ(217, event->getToolMinor(0));
+ ASSERT_EQ(227, event->getToolMinor(1));
+
+ ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
+ ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
+ ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
+ ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
+ ASSERT_EQ(218, event->getOrientation(0));
+ ASSERT_EQ(228, event->getOrientation(1));
+}
+
+TEST_F(MotionEventTest, Properties) {
+ MotionEvent event;
+
+ // Initialize, add samples and check properties.
+ initializeEventWithHistory(&event);
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+
+ // Set source.
+ event.setSource(AINPUT_SOURCE_JOYSTICK);
+ ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+
+ // Set action.
+ event.setAction(AMOTION_EVENT_ACTION_CANCEL);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
+
+ // Set meta state.
+ event.setMetaState(AMETA_CTRL_ON);
+ ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
+}
+
+TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ MotionEvent copy;
+ copy.copyFrom(&event, true /*keepHistory*/);
+
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+}
+
+TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ MotionEvent copy;
+ copy.copyFrom(&event, false /*keepHistory*/);
+
+ ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
+ ASSERT_EQ(0U, copy.getHistorySize());
+
+ ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
+ ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
+
+ ASSERT_EQ(event.getEventTime(), copy.getEventTime());
+
+ ASSERT_EQ(event.getX(0), copy.getX(0));
+}
+
+TEST_F(MotionEventTest, OffsetLocation) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ event.offsetLocation(5.0f, -2.0f);
+
+ ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
+ ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
+}
+
+TEST_F(MotionEventTest, Scale) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ event.scale(2.0f);
+
+ ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
+ ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
+
+ ASSERT_EQ(210 * 2, event.getRawX(0));
+ ASSERT_EQ(211 * 2, event.getRawY(0));
+ ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
+ ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
+ ASSERT_EQ(212, event.getPressure(0));
+ ASSERT_EQ(213, event.getSize(0));
+ ASSERT_EQ(214 * 2, event.getTouchMajor(0));
+ ASSERT_EQ(215 * 2, event.getTouchMinor(0));
+ ASSERT_EQ(216 * 2, event.getToolMajor(0));
+ ASSERT_EQ(217 * 2, event.getToolMinor(0));
+ ASSERT_EQ(218, event.getOrientation(0));
+}
+
+TEST_F(MotionEventTest, Parcel) {
+ Parcel parcel;
+
+ MotionEvent inEvent;
+ initializeEventWithHistory(&inEvent);
+ MotionEvent outEvent;
+
+ // Round trip.
+ inEvent.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outEvent.readFromParcel(&parcel);
+
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
+}
+
+TEST_F(MotionEventTest, Transform) {
+ // Generate some points on a circle.
+ // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
+ // of ARC * i degrees clockwise relative to the Y axis.
+ // The geometrical representation is irrelevant to the test, it's just easy to generate
+ // and check rotation. We set the orientation to the same angle.
+ // Coordinate system: down is increasing Y, right is increasing X.
+ const float PI_180 = float(M_PI / 180);
+ const float RADIUS = 10;
+ const float ARC = 36;
+ const float ROTATION = ARC * 2;
+
+ const size_t pointerCount = 11;
+ int pointerIds[pointerCount];
+ PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ float angle = float(i * ARC * PI_180);
+ pointerIds[i] = i;
+ pointerCoords[i].clear();
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
+ }
+ MotionEvent event;
+ event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ float originalRawX = 0 + 3;
+ float originalRawY = -RADIUS + 2;
+
+ // Check original raw X and Y assumption.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+ // Now translate the motion event so the circle's origin is at (0,0).
+ event.offsetLocation(-3, -2);
+
+ // Offsetting the location should preserve the raw X and Y of the first point.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+ // Apply a rotation about the origin by ROTATION degrees clockwise.
+ SkMatrix matrix;
+ matrix.setRotate(ROTATION);
+ event.transform(&matrix);
+
+ // Check the points.
+ for (size_t i = 0; i < pointerCount; i++) {
+ float angle = float((i * ARC + ROTATION) * PI_180);
+ ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
+ ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
+ ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
+ }
+
+ // Applying the transformation should preserve the raw X and Y of the first point.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+}
+
+} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index 903fcaf..6e18a4f 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include <ui/InputTransport.h>
#include <utils/Timers.h>
@@ -159,15 +171,17 @@
sampleEventTimes.push(i + 10);
for (size_t j = 0; j < pointerCount; j++) {
samplePointerCoords.push();
- samplePointerCoords.editTop().x = 100 * i + j;
- samplePointerCoords.editTop().y = 200 * i + j;
- samplePointerCoords.editTop().pressure = 0.5 * i + j;
- samplePointerCoords.editTop().size = 0.7 * i + j;
- samplePointerCoords.editTop().touchMajor = 1.5 * i + j;
- samplePointerCoords.editTop().touchMinor = 1.7 * i + j;
- samplePointerCoords.editTop().toolMajor = 2.5 * i + j;
- samplePointerCoords.editTop().toolMinor = 2.7 * i + j;
- samplePointerCoords.editTop().orientation = 3.5 * i + j;
+ PointerCoords& pc = samplePointerCoords.editTop();
+ pc.clear();
+ pc.setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i + j);
}
}
@@ -239,27 +253,27 @@
for (size_t i = 0; i < pointerCount; i++) {
SCOPED_TRACE(i);
size_t offset = sampleIndex * pointerCount + i;
- EXPECT_EQ(samplePointerCoords[offset].x,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
motionEvent->getHistoricalRawX(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].y,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
motionEvent->getHistoricalRawY(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].x + xOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
motionEvent->getHistoricalX(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].y + yOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
motionEvent->getHistoricalY(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].pressure,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
motionEvent->getHistoricalPressure(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].size,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
motionEvent->getHistoricalSize(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].touchMajor,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
motionEvent->getHistoricalTouchMajor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].touchMinor,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
motionEvent->getHistoricalTouchMinor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].toolMajor,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
motionEvent->getHistoricalToolMajor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].toolMinor,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
motionEvent->getHistoricalToolMinor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].orientation,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
motionEvent->getHistoricalOrientation(i, sampleIndex));
}
}
@@ -269,17 +283,28 @@
for (size_t i = 0; i < pointerCount; i++) {
SCOPED_TRACE(i);
size_t offset = lastSampleIndex * pointerCount + i;
- EXPECT_EQ(samplePointerCoords[offset].x, motionEvent->getRawX(i));
- EXPECT_EQ(samplePointerCoords[offset].y, motionEvent->getRawY(i));
- EXPECT_EQ(samplePointerCoords[offset].x + xOffset, motionEvent->getX(i));
- EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i));
- EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i));
- EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i));
- EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i));
- EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i));
- EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i));
- EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i));
- EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
+ motionEvent->getRawX(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ motionEvent->getRawY(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
+ motionEvent->getX(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
+ motionEvent->getY(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ motionEvent->getPressure(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ motionEvent->getSize(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ motionEvent->getTouchMajor(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ motionEvent->getTouchMinor(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ motionEvent->getToolMajor(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ motionEvent->getToolMinor(i));
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+ motionEvent->getOrientation(i));
}
status = mConsumer->sendFinishedSignal(false);
@@ -328,7 +353,8 @@
const size_t pointerCount = 1;
int32_t pointerIds[pointerCount] = { 0 };
- PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
+ PointerCoords pointerCoords[pointerCount];
+ pointerCoords[0].clear();
status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
pointerCount, pointerIds, pointerCoords);
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
index 2bdc0ce..062e6d7 100644
--- a/libs/utils/SystemClock.cpp
+++ b/libs/utils/SystemClock.cpp
@@ -19,7 +19,7 @@
* System clock functions.
*/
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#include <linux/rtc.h>
#include <utils/Atomic.h>
@@ -50,7 +50,7 @@
return -1;
#else
struct timeval tv;
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timespec ts;
int fd;
int res;
@@ -66,7 +66,7 @@
LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
fd = open("/dev/alarm", O_RDWR);
if(fd < 0) {
LOGW("Unable to open alarm driver: %s\n", strerror(errno));
@@ -106,7 +106,7 @@
*/
int64_t elapsedRealtime()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
static int s_fd = -1;
if (s_fd == -1) {
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index b1bd828..35dcbcb 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -739,7 +739,7 @@
wp<Thread> weak(strong);
self->mHoldSelf.clear();
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 8c78d60..ad2bf95 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3065,8 +3065,7 @@
* This function is responsible for stopping the preview
*/
long stopPreview() {
- nativeStopPreview();
- return mPreviewProgress;
+ return nativeStopPreview();
}
/**
@@ -3999,7 +3998,7 @@
int framewidth, int frameheight, int surfacewidth, int surfaceheight, long timeMs)
throws IllegalArgumentException, IllegalStateException, RuntimeException;
- private native void nativeStopPreview();
+ private native int nativeStopPreview();
private native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
int frameDuration, int channels, int sampleCount);
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index 95f002c..3e8fe94 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -173,6 +173,7 @@
mDurationMs = durationMs;
invalidate();
+ mNativeHelper.setGeneratePreview(true);
}
/**
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 1ba5beb..23081f8 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -208,7 +208,7 @@
jobject object,
jobject audioSettingObject);
-static void videoEditor_stopPreview(JNIEnv* pEnv,
+static int videoEditor_stopPreview(JNIEnv* pEnv,
jobject thiz);
static jobject
@@ -283,8 +283,8 @@
{"nativeRenderMediaItemPreviewFrame",
"(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I",
(int *)videoEditor_renderMediaItemPreviewFrame },
- {"nativeStopPreview", "()V",
- (void *)videoEditor_stopPreview },
+ {"nativeStopPreview", "()I",
+ (int *)videoEditor_stopPreview },
{"stopEncoding", "()V",
(void *)videoEditor_stopEncoding },
{"release", "()V",
@@ -482,11 +482,13 @@
pContext->pVM->DetachCurrentThread();
}
-static void videoEditor_stopPreview(JNIEnv* pEnv,
+static int videoEditor_stopPreview(JNIEnv* pEnv,
jobject thiz)
{
ManualEditContext* pContext = M4OSA_NULL;
bool needToBeLoaded = true;
+ M4OSA_UInt32 lastProgressTimeMs = 0;
+
// Get the context.
pContext =
(ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
@@ -495,12 +497,14 @@
videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
(M4OSA_NULL == pContext),
"not initialized");
- pContext->mPreviewController->stopPreview();
+ lastProgressTimeMs = pContext->mPreviewController->stopPreview();
if (pContext->mOverlayFileName != NULL) {
M4OSA_free((M4OSA_MemAddr32)pContext->mOverlayFileName);
pContext->mOverlayFileName = NULL;
}
+
+ return lastProgressTimeMs;
}
static void videoEditor_clearSurface(JNIEnv* pEnv,
diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
index 014cd95..73a7c9c 100755
--- a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
@@ -122,12 +122,26 @@
&gotten, pEnv, file, NULL, M4OSA_NULL);
result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead);
+
+ if(M4NO_ERROR != result) {
+ // Free the file path.
+ videoEditOsal_free(pFile);
+ pFile = M4OSA_NULL;
+ }
+
videoEditJava_checkAndThrowIllegalArgumentException(&gotten, pEnv,
(M4NO_ERROR != result), "file not found");
- if(M4NO_ERROR != result)
- return(properties);
- result = M4OSA_fileReadClose(context);
- context = M4OSA_NULL;
+
+ // Close the file and free the file context
+ if (context != NULL) {
+ result = M4OSA_fileReadClose(context);
+ context = M4OSA_NULL;
+ }
+
+ // Return if Error
+ if (M4NO_ERROR != result) {
+ return (properties); // NULL
+ }
// Check if the file path is valid.
if (gotten)
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 439e4ce..60bdd62 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -732,18 +732,14 @@
return TEST_PLAYER;
}
- char value[PROPERTY_VALUE_MAX];
- if (!property_get("media.httplive.disable-nuplayer", value, NULL)
- || (strcasecmp(value, "true") && strcmp(value, "1"))) {
- if (!strncasecmp("http://", url, 7)) {
- size_t len = strlen(url);
- if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
- return NU_PLAYER;
- }
+ if (!strncasecmp("http://", url, 7)) {
+ size_t len = strlen(url);
+ if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
+ return NU_PLAYER;
+ }
- if (strstr(url,"m3u8")) {
- return NU_PLAYER;
- }
+ if (strstr(url,"m3u8")) {
+ return NU_PLAYER;
}
}
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
new file mode 100644
index 0000000..4203b6e
--- /dev/null
+++ b/media/libstagefright/AACExtractor.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AACExtractor"
+#include <utils/Log.h>
+
+#include "include/AACExtractor.h"
+#include "include/avc_utils.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <utils/String8.h>
+
+namespace android {
+
+#define ADTS_HEADER_LENGTH 7
+
+class AACSource : public MediaSource {
+public:
+ AACSource(const sp<DataSource> &source,
+ const sp<MetaData> &meta,
+ const Vector<uint64_t> &offset_vector,
+ int64_t frame_duration_us);
+
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+
+protected:
+ virtual ~AACSource();
+
+private:
+ static const size_t kMaxFrameSize;
+ sp<DataSource> mDataSource;
+ sp<MetaData> mMeta;
+
+ off64_t mOffset;
+ int64_t mCurrentTimeUs;
+ bool mStarted;
+ MediaBufferGroup *mGroup;
+
+ Vector<uint64_t> mOffsetVector;
+ int64_t mFrameDurationUs;
+
+ AACSource(const AACSource &);
+ AACSource &operator=(const AACSource &);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Returns the sample rate based on the sampling frequency index
+uint32_t get_sample_rate(const uint8_t sf_index)
+{
+ static const uint32_t sample_rates[] =
+ {
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000
+ };
+
+ if (sf_index < sizeof(sample_rates) / sizeof(sample_rates[0])) {
+ return sample_rates[sf_index];
+ }
+
+ return 0;
+}
+
+static size_t getFrameSize(const sp<DataSource> &source, off64_t offset) {
+ size_t frameSize = 0;
+
+ uint8_t syncword[2];
+ if (source->readAt(0, &syncword, 2) != 2) {
+ return 0;
+ }
+ if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) {
+ return 0;
+ }
+
+ uint8_t protectionAbsent;
+ if (source->readAt(offset + 1, &protectionAbsent, 1) < 1) {
+ return 0;
+ }
+ protectionAbsent &= 0x1;
+
+ uint8_t header[3];
+ if (source->readAt(offset + 3, &header, 3) < 3) {
+ return 0;
+ }
+
+ frameSize = (header[0] & 0x3) << 11 | header[1] << 3 | header[2] >> 5;
+ frameSize += ADTS_HEADER_LENGTH + protectionAbsent ? 0 : 2;
+
+ return frameSize;
+}
+
+AACExtractor::AACExtractor(const sp<DataSource> &source)
+ : mDataSource(source),
+ mInitCheck(NO_INIT),
+ mFrameDurationUs(0) {
+ String8 mimeType;
+ float confidence;
+ if (!SniffAAC(mDataSource, &mimeType, &confidence, NULL)) {
+ return;
+ }
+
+ uint8_t profile, sf_index, channel, header[2];
+ if (mDataSource->readAt(2, &header, 2) < 2) {
+ return;
+ }
+
+ profile = (header[0] >> 6) & 0x3;
+ sf_index = (header[0] >> 2) & 0xf;
+ uint32_t sr = get_sample_rate(sf_index);
+ if (sr == 0) {
+ return;
+ }
+ channel = (header[0] & 0x1) << 2 | (header[1] >> 6);
+
+ mMeta = MakeAACCodecSpecificData(profile, sf_index, channel);
+
+ off64_t offset = 0;
+ off64_t streamSize, numFrames = 0;
+ size_t frameSize = 0;
+ int64_t duration = 0;
+
+ if (mDataSource->getSize(&streamSize) == OK) {
+ while (offset < streamSize) {
+ if ((frameSize = getFrameSize(source, offset)) == 0) {
+ return;
+ }
+
+ mOffsetVector.push(offset);
+
+ offset += frameSize;
+ numFrames ++;
+ }
+
+ // Round up and get the duration
+ mFrameDurationUs = (1024 * 1000000ll + (sr - 1)) / sr;
+ duration = numFrames * mFrameDurationUs;
+ mMeta->setInt64(kKeyDuration, duration);
+ }
+
+ mInitCheck = OK;
+}
+
+AACExtractor::~AACExtractor() {
+}
+
+sp<MetaData> AACExtractor::getMetaData() {
+ sp<MetaData> meta = new MetaData;
+
+ if (mInitCheck != OK) {
+ return meta;
+ }
+
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC_ADTS);
+
+ return meta;
+}
+
+size_t AACExtractor::countTracks() {
+ return mInitCheck == OK ? 1 : 0;
+}
+
+sp<MediaSource> AACExtractor::getTrack(size_t index) {
+ if (mInitCheck != OK || index != 0) {
+ return NULL;
+ }
+
+ return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs);
+}
+
+sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+ if (mInitCheck != OK || index != 0) {
+ return NULL;
+ }
+
+ return mMeta;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// 8192 = 2^13, 13bit AAC frame size (in bytes)
+const size_t AACSource::kMaxFrameSize = 8192;
+
+AACSource::AACSource(
+ const sp<DataSource> &source, const sp<MetaData> &meta,
+ const Vector<uint64_t> &offset_vector,
+ int64_t frame_duration_us)
+ : mDataSource(source),
+ mMeta(meta),
+ mOffset(0),
+ mCurrentTimeUs(0),
+ mStarted(false),
+ mGroup(NULL),
+ mOffsetVector(offset_vector),
+ mFrameDurationUs(frame_duration_us) {
+}
+
+AACSource::~AACSource() {
+ if (mStarted) {
+ stop();
+ }
+}
+
+status_t AACSource::start(MetaData *params) {
+ CHECK(!mStarted);
+
+ mOffset = 0;
+ mCurrentTimeUs = 0;
+ mGroup = new MediaBufferGroup;
+ mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
+ mStarted = true;
+
+ return OK;
+}
+
+status_t AACSource::stop() {
+ CHECK(mStarted);
+
+ delete mGroup;
+ mGroup = NULL;
+
+ mStarted = false;
+ return OK;
+}
+
+sp<MetaData> AACSource::getFormat() {
+ return mMeta;
+}
+
+status_t AACSource::read(
+ MediaBuffer **out, const ReadOptions *options) {
+ *out = NULL;
+
+ int64_t seekTimeUs;
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ if (mFrameDurationUs > 0) {
+ int64_t seekFrame = seekTimeUs / mFrameDurationUs;
+ mCurrentTimeUs = seekFrame * mFrameDurationUs;
+
+ mOffset = mOffsetVector.itemAt(seekFrame);
+ }
+ }
+
+ size_t frameSize, frameSizeWithoutHeader;
+ if ((frameSize = getFrameSize(mDataSource, mOffset)) == 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ MediaBuffer *buffer;
+ status_t err = mGroup->acquire_buffer(&buffer);
+ if (err != OK) {
+ return err;
+ }
+
+ frameSizeWithoutHeader = frameSize - ADTS_HEADER_LENGTH;
+ if (mDataSource->readAt(mOffset + ADTS_HEADER_LENGTH, buffer->data(),
+ frameSizeWithoutHeader) != (ssize_t)frameSizeWithoutHeader) {
+ buffer->release();
+ buffer = NULL;
+
+ return ERROR_IO;
+ }
+
+ buffer->set_range(0, frameSizeWithoutHeader);
+ buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
+ buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+
+ mOffset += frameSize;
+ mCurrentTimeUs += mFrameDurationUs;
+
+ *out = buffer;
+ return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool SniffAAC(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *) {
+ uint8_t header[2];
+
+ if (source->readAt(0, &header, 2) != 2) {
+ return false;
+ }
+
+ // ADTS syncword
+ if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) {
+ *mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
+ *confidence = 0.2;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace android
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 029b238..80eb59f 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -5,6 +5,7 @@
LOCAL_SRC_FILES:= \
ACodec.cpp \
+ AACExtractor.cpp \
AMRExtractor.cpp \
AMRWriter.cpp \
AudioPlayer.cpp \
@@ -57,7 +58,8 @@
$(TOP)/frameworks/base/include/media/stagefright/openmax \
$(TOP)/external/flac/include \
$(TOP)/external/tremolo \
- $(TOP)/frameworks/base/media/libstagefright/rtsp
+ $(TOP)/frameworks/base/media/libstagefright/rtsp \
+ $(TOP)/external/openssl/include \
LOCAL_SHARED_LIBRARIES := \
libbinder \
@@ -71,7 +73,8 @@
libstagefright_yuv \
libcamera_client \
libdrmframework \
- libcrypto
+ libcrypto \
+ libssl
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 7a1d73b..bbdec02 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -18,38 +18,54 @@
#define LOG_TAG "AudioSource"
#include <utils/Log.h>
-#include <media/stagefright/AudioSource.h>
-
#include <media/AudioRecord.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/AudioSource.h>
+#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <cutils/properties.h>
#include <stdlib.h>
namespace android {
+static void AudioRecordCallbackFunction(int event, void *user, void *info) {
+ AudioSource *source = (AudioSource *) user;
+ switch (event) {
+ case AudioRecord::EVENT_MORE_DATA: {
+ source->dataCallbackTimestamp(*((AudioRecord::Buffer *) info), systemTime() / 1000);
+ break;
+ }
+ case AudioRecord::EVENT_OVERRUN: {
+ LOGW("AudioRecord reported overrun!");
+ break;
+ }
+ default:
+ // does nothing
+ break;
+ }
+}
+
AudioSource::AudioSource(
int inputSource, uint32_t sampleRate, uint32_t channels)
: mStarted(false),
- mCollectStats(false),
+ mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
- mTotalLostFrames(0),
- mPrevLostBytes(0),
- mGroup(NULL) {
+ mNumFramesReceived(0),
+ mNumClientOwnedBuffers(0) {
LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
CHECK(channels == 1 || channels == 2);
uint32_t flags = AudioRecord::RECORD_AGC_ENABLE |
AudioRecord::RECORD_NS_ENABLE |
AudioRecord::RECORD_IIR_ENABLE;
-
mRecord = new AudioRecord(
inputSource, sampleRate, AudioSystem::PCM_16_BIT,
channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,
4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
- flags);
+ flags,
+ AudioRecordCallbackFunction,
+ this);
mInitCheck = mRecord->initCheck();
}
@@ -68,6 +84,7 @@
}
status_t AudioSource::start(MetaData *params) {
+ Mutex::Autolock autoLock(mLock);
if (mStarted) {
return UNKNOWN_ERROR;
}
@@ -76,12 +93,6 @@
return NO_INIT;
}
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.stagefright.record-stats", value, NULL)
- && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
- mCollectStats = true;
- }
-
mTrackMaxAmplitude = false;
mMaxAmplitude = 0;
mInitialReadTimeUs = 0;
@@ -92,9 +103,6 @@
}
status_t err = mRecord->start();
if (err == OK) {
- mGroup = new MediaBufferGroup;
- mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
-
mStarted = true;
} else {
delete mRecord;
@@ -105,7 +113,25 @@
return err;
}
+void AudioSource::releaseQueuedFrames_l() {
+ LOGV("releaseQueuedFrames_l");
+ List<MediaBuffer *>::iterator it;
+ while (!mBuffersReceived.empty()) {
+ it = mBuffersReceived.begin();
+ (*it)->release();
+ mBuffersReceived.erase(it);
+ }
+}
+
+void AudioSource::waitOutstandingEncodingFrames_l() {
+ LOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers);
+ while (mNumClientOwnedBuffers > 0) {
+ mFrameEncodingCompletionCondition.wait(mLock);
+ }
+}
+
status_t AudioSource::stop() {
+ Mutex::Autolock autoLock(mLock);
if (!mStarted) {
return UNKNOWN_ERROR;
}
@@ -114,29 +140,23 @@
return NO_INIT;
}
- mRecord->stop();
-
- delete mGroup;
- mGroup = NULL;
-
mStarted = false;
-
- if (mCollectStats) {
- LOGI("Total lost audio frames: %lld",
- mTotalLostFrames + (mPrevLostBytes >> 1));
- }
+ mRecord->stop();
+ waitOutstandingEncodingFrames_l();
+ releaseQueuedFrames_l();
return OK;
}
sp<MetaData> AudioSource::getFormat() {
+ Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
return 0;
}
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeySampleRate, mRecord->getSampleRate());
+ meta->setInt32(kKeySampleRate, mSampleRate);
meta->setInt32(kKeyChannelCount, mRecord->channelCount());
meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
@@ -177,121 +197,131 @@
status_t AudioSource::read(
MediaBuffer **out, const ReadOptions *options) {
+ Mutex::Autolock autoLock(mLock);
+ *out = NULL;
if (mInitCheck != OK) {
return NO_INIT;
}
- int64_t readTimeUs = systemTime() / 1000;
- *out = NULL;
-
- MediaBuffer *buffer;
- CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
-
- int err = 0;
- if (mStarted) {
-
- uint32_t numFramesRecorded;
- mRecord->getPosition(&numFramesRecorded);
-
-
- if (numFramesRecorded == 0 && mPrevSampleTimeUs == 0) {
- mInitialReadTimeUs = readTimeUs;
- // Initial delay
- if (mStartTimeUs > 0) {
- mStartTimeUs = readTimeUs - mStartTimeUs;
- } else {
- // Assume latency is constant.
- mStartTimeUs += mRecord->latency() * 1000;
- }
- mPrevSampleTimeUs = mStartTimeUs;
- }
-
- uint32_t sampleRate = mRecord->getSampleRate();
-
- // Insert null frames when lost frames are detected.
- int64_t timestampUs = mPrevSampleTimeUs;
- uint32_t numLostBytes = mRecord->getInputFramesLost() << 1;
- numLostBytes += mPrevLostBytes;
-#if 0
- // Simulate lost frames
- numLostBytes = ((rand() * 1.0 / RAND_MAX)) * 2 * kMaxBufferSize;
- numLostBytes &= 0xFFFFFFFE; // Alignment requirement
-
- // Reduce the chance to lose
- if (rand() * 1.0 / RAND_MAX >= 0.05) {
- numLostBytes = 0;
- }
-#endif
- if (numLostBytes > 0) {
- if (numLostBytes > kMaxBufferSize) {
- mPrevLostBytes = numLostBytes - kMaxBufferSize;
- numLostBytes = kMaxBufferSize;
- } else {
- mPrevLostBytes = 0;
- }
-
- CHECK_EQ(numLostBytes & 1, 0);
- timestampUs += ((1000000LL * (numLostBytes >> 1)) +
- (sampleRate >> 1)) / sampleRate;
-
- if (mCollectStats) {
- mTotalLostFrames += (numLostBytes >> 1);
- }
- memset(buffer->data(), 0, numLostBytes);
- buffer->set_range(0, numLostBytes);
- if (numFramesRecorded == 0) {
- buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
- }
- buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs + mPrevSampleTimeUs);
- buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
- mPrevSampleTimeUs = timestampUs;
- *out = buffer;
- return OK;
- }
-
- ssize_t n = mRecord->read(buffer->data(), buffer->size());
- if (n <= 0) {
- buffer->release();
- LOGE("Read from AudioRecord returns %d", n);
- return UNKNOWN_ERROR;
- }
-
- int64_t recordDurationUs = (1000000LL * n >> 1) / sampleRate;
- timestampUs += recordDurationUs;
-
- if (mPrevSampleTimeUs - mStartTimeUs < kAutoRampStartUs) {
- // Mute the initial video recording signal
- memset((uint8_t *) buffer->data(), 0, n);
- } else if (mPrevSampleTimeUs - mStartTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
- int32_t autoRampDurationFrames =
- (kAutoRampDurationUs * sampleRate + 500000LL) / 1000000LL;
-
- int32_t autoRampStartFrames =
- (kAutoRampStartUs * sampleRate + 500000LL) / 1000000LL;
-
- int32_t nFrames = numFramesRecorded - autoRampStartFrames;
- rampVolume(nFrames, autoRampDurationFrames, (uint8_t *) buffer->data(), n);
- }
- if (mTrackMaxAmplitude) {
- trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
- }
-
- if (numFramesRecorded == 0) {
- buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
- }
-
- buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs + mPrevSampleTimeUs);
- buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
- mPrevSampleTimeUs = timestampUs;
- LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
- mStartTimeUs, sampleRate, timestampUs);
-
- buffer->set_range(0, n);
-
- *out = buffer;
+ while (mStarted && mBuffersReceived.empty()) {
+ mFrameAvailableCondition.wait(mLock);
+ }
+ if (!mStarted) {
return OK;
}
+ MediaBuffer *buffer = *mBuffersReceived.begin();
+ mBuffersReceived.erase(mBuffersReceived.begin());
+ ++mNumClientOwnedBuffers;
+ buffer->setObserver(this);
+ buffer->add_ref();
+
+ // Mute/suppress the recording sound
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ int64_t elapsedTimeUs = timeUs - mStartTimeUs;
+ if (elapsedTimeUs < kAutoRampStartUs) {
+ memset((uint8_t *) buffer->data(), 0, buffer->range_length());
+ } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
+ int32_t autoRampDurationFrames =
+ (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL;
+
+ int32_t autoRampStartFrames =
+ (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL;
+
+ int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
+ rampVolume(nFrames, autoRampDurationFrames,
+ (uint8_t *) buffer->data(), buffer->range_length());
+ }
+
+ // Track the max recording signal amplitude.
+ if (mTrackMaxAmplitude) {
+ trackMaxAmplitude(
+ (int16_t *) buffer->data(), buffer->range_length() >> 1);
+ }
+
+ *out = buffer;
+ return OK;
+}
+
+void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
+ LOGV("signalBufferReturned: %p", buffer->data());
+ Mutex::Autolock autoLock(mLock);
+ --mNumClientOwnedBuffers;
+ buffer->setObserver(0);
+ buffer->release();
+ mFrameEncodingCompletionCondition.signal();
+ return;
+}
+
+status_t AudioSource::dataCallbackTimestamp(
+ const AudioRecord::Buffer& audioBuffer, int64_t timeUs) {
+ LOGV("dataCallbackTimestamp: %lld us", timeUs);
+ Mutex::Autolock autoLock(mLock);
+ if (!mStarted) {
+ LOGW("Spurious callback from AudioRecord. Drop the audio data.");
+ return OK;
+ }
+
+ // Drop retrieved and previously lost audio data.
+ if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
+ mRecord->getInputFramesLost();
+ LOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
+ return OK;
+ }
+
+ if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
+ mInitialReadTimeUs = timeUs;
+ // Initial delay
+ if (mStartTimeUs > 0) {
+ mStartTimeUs = timeUs - mStartTimeUs;
+ } else {
+ // Assume latency is constant.
+ mStartTimeUs += mRecord->latency() * 1000;
+ }
+ mPrevSampleTimeUs = mStartTimeUs;
+ }
+
+ int64_t timestampUs = mPrevSampleTimeUs;
+
+ size_t numLostBytes = 0;
+ if (mNumFramesReceived > 0) { // Ignore earlier frame lost
+ // getInputFramesLost() returns the number of lost frames.
+ // Convert number of frames lost to number of bytes lost.
+ numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
+ }
+
+ CHECK_EQ(numLostBytes & 1, 0u);
+ CHECK_EQ(audioBuffer.size & 1, 0u);
+ size_t bufferSize = numLostBytes + audioBuffer.size;
+ MediaBuffer *buffer = new MediaBuffer(bufferSize);
+ if (numLostBytes > 0) {
+ memset(buffer->data(), 0, numLostBytes);
+ memcpy((uint8_t *) buffer->data() + numLostBytes,
+ audioBuffer.i16, audioBuffer.size);
+ } else {
+ if (audioBuffer.size == 0) {
+ LOGW("Nothing is available from AudioRecord callback buffer");
+ buffer->release();
+ return OK;
+ }
+ memcpy((uint8_t *) buffer->data(),
+ audioBuffer.i16, audioBuffer.size);
+ }
+
+ buffer->set_range(0, bufferSize);
+ timestampUs += ((1000000LL * (bufferSize >> 1)) +
+ (mSampleRate >> 1)) / mSampleRate;
+
+ if (mNumFramesReceived == 0) {
+ buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
+ }
+ buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
+ buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
+ mPrevSampleTimeUs = timestampUs;
+ mNumFramesReceived += buffer->range_length() / sizeof(int16_t);
+ mBuffersReceived.push_back(buffer);
+ mFrameAvailableCondition.signal();
return OK;
}
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index cb08023..b1d3630 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -44,7 +44,6 @@
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/foundation/AMessage.h>
-#include "include/LiveSession.h"
#define USE_SURFACE_ALLOC 1
#define FRAME_DROP_FREQ 7
@@ -233,17 +232,6 @@
mUri = uri;
- if (!strncmp("http://", uri, 7)) {
- // Hack to support http live.
-
- size_t len = strlen(uri);
- if (!strcasecmp(&uri[len - 5], ".m3u8")
- || strstr(&uri[7], "m3u8") != NULL) {
- mUri = "httplive://";
- mUri.append(&uri[7]);
- }
- }
-
if (headers) {
mUriHeaders = *headers;
}
@@ -376,14 +364,11 @@
}
void AwesomePlayer::reset() {
- LOGI("reset");
-
Mutex::Autolock autoLock(mLock);
reset_l();
}
void AwesomePlayer::reset_l() {
- LOGI("reset_l");
mDisplayWidth = 0;
mDisplayHeight = 0;
@@ -411,10 +396,6 @@
}
}
- if (mFlags & PREPARING) {
- LOGI("waiting until preparation is completed.");
- }
-
while (mFlags & PREPARING) {
mPreparedCondition.wait(mLock);
}
@@ -438,8 +419,6 @@
}
mAudioSource.clear();
- LOGI("audio source cleared");
-
mTimeSource = NULL;
delete mAudioPlayer;
@@ -457,11 +436,6 @@
mRTSPController.clear();
}
- if (mLiveSession != NULL) {
- mLiveSession->disconnect();
- mLiveSession.clear();
- }
-
if (mVideoSource != NULL) {
mVideoSource->stop();
@@ -476,8 +450,6 @@
IPCThreadState::self()->flushCommands();
}
- LOGI("video source cleared");
-
mDurationUs = -1;
mFlags = 0;
mExtractorFlags = 0;
@@ -494,8 +466,6 @@
mFileSource.clear();
mBitrate = -1;
-
- LOGI("reset_l completed");
}
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -668,35 +638,6 @@
postBufferingEvent_l();
}
-void AwesomePlayer::partial_reset_l() {
- // Only reset the video renderer and shut down the video decoder.
- // Then instantiate a new video decoder and resume video playback.
-
- mVideoRenderer.clear();
-
- if (mVideoBuffer) {
- mVideoBuffer->release();
- mVideoBuffer = NULL;
- }
-
- {
- mVideoSource->stop();
-
- // The following hack is necessary to ensure that the OMX
- // component is completely released by the time we may try
- // to instantiate it again.
- wp<MediaSource> tmp = mVideoSource;
- mVideoSource.clear();
- while (tmp.promote() != NULL) {
- usleep(1000);
- }
- IPCThreadState::self()->flushCommands();
- }
-
- CHECK_EQ((status_t)OK,
- initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData));
-}
-
void AwesomePlayer::onStreamDone() {
// Posted whenever any stream finishes playing.
@@ -706,21 +647,7 @@
}
mStreamDoneEventPending = false;
- if (mStreamDoneStatus == INFO_DISCONTINUITY) {
- // This special status is returned because an http live stream's
- // video stream switched to a different bandwidth at this point
- // and future data may have been encoded using different parameters.
- // This requires us to shutdown the video decoder and reinstantiate
- // a fresh one.
-
- LOGV("INFO_DISCONTINUITY");
-
- CHECK(mVideoSource != NULL);
-
- partial_reset_l();
- postVideoEvent_l();
- return;
- } else if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
+ if (mStreamDoneStatus != ERROR_END_OF_STREAM) {
LOGV("MEDIA_ERROR %d", mStreamDoneStatus);
notifyListener_l(
@@ -1554,7 +1481,8 @@
status_t AwesomePlayer::finishSetDataSource_l() {
sp<DataSource> dataSource;
- if (!strncasecmp("http://", mUri.string(), 7)) {
+ if (!strncasecmp("http://", mUri.string(), 7)
+ || !strncasecmp("https://", mUri.string(), 8)) {
mConnectingDataSource = new NuHTTPDataSource;
mLock.unlock();
@@ -1606,29 +1534,6 @@
LOGI("Prepare cancelled while waiting for initial cache fill.");
return UNKNOWN_ERROR;
}
- } else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
- String8 uri("http://");
- uri.append(mUri.string() + 11);
-
- if (mLooper == NULL) {
- mLooper = new ALooper;
- mLooper->setName("httplive");
- mLooper->start();
- }
-
- mLiveSession = new LiveSession;
- mLooper->registerHandler(mLiveSession);
-
- mLiveSession->connect(uri.string());
- dataSource = mLiveSession->getDataSource();
-
- sp<MediaExtractor> extractor =
- MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
-
- static_cast<MPEG2TSExtractor *>(extractor.get())
- ->setLiveSession(mLiveSession);
-
- return setDataSource_l(extractor);
} else if (!strncasecmp("rtsp://", mUri.string(), 7)) {
if (mLooper == NULL) {
mLooper = new ALooper;
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 66e0657..8a24bc45 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -598,8 +598,7 @@
}
if (mNumGlitches > 0) {
- LOGW("%d long delays between neighboring video frames during",
- mNumGlitches);
+ LOGW("%d long delays between neighboring video frames", mNumGlitches);
}
CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
@@ -696,10 +695,9 @@
int32_t msgType, const sp<IMemory> &data) {
LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
Mutex::Autolock autoLock(mLock);
- if (!mStarted) {
+ if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
+ LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
releaseOneRecordingFrame(data);
- ++mNumFramesReceived;
- ++mNumFramesDropped;
return;
}
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index e06fa81..3b38208 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -24,6 +24,7 @@
#include "include/NuHTTPDataSource.h"
#include "include/DRMExtractor.h"
#include "include/FLACExtractor.h"
+#include "include/AACExtractor.h"
#include "matroska/MatroskaExtractor.h"
@@ -109,6 +110,7 @@
RegisterSniffer(SniffAMR);
RegisterSniffer(SniffMPEG2TS);
RegisterSniffer(SniffMP3);
+ RegisterSniffer(SniffAAC);
char value[PROPERTY_VALUE_MAX];
if (property_get("drm.service.enabled", value, NULL)
@@ -123,7 +125,8 @@
sp<DataSource> source;
if (!strncasecmp("file://", uri, 7)) {
source = new FileSource(uri + 7);
- } else if (!strncasecmp("http://", uri, 7)) {
+ } else if (!strncasecmp("http://", uri, 7)
+ || !strncasecmp("https://", uri, 8)) {
sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
if (httpSource->connect(uri, headers) != OK) {
return NULL;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 77a61a5..498c7b8 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -34,6 +34,8 @@
#include <media/stagefright/foundation/ADebug.h>
+#include <openssl/ssl.h>
+
namespace android {
// static
@@ -41,11 +43,18 @@
HTTPStream::HTTPStream()
: mState(READY),
- mSocket(-1) {
+ mSocket(-1),
+ mSSLContext(NULL),
+ mSSL(NULL) {
}
HTTPStream::~HTTPStream() {
disconnect();
+
+ if (mSSLContext != NULL) {
+ SSL_CTX_free((SSL_CTX *)mSSLContext);
+ mSSLContext = NULL;
+ }
}
static bool MakeSocketBlocking(int s, bool blocking) {
@@ -198,7 +207,11 @@
return MySendReceive(s, data, size, flags, false /* sendData */);
}
-status_t HTTPStream::connect(const char *server, int port) {
+status_t HTTPStream::connect(const char *server, int port, bool https) {
+ if (port < 0) {
+ port = https ? 443 : 80;
+ }
+
Mutex::Autolock autoLock(mLock);
status_t err = OK;
@@ -249,6 +262,47 @@
return res;
}
+ if (https) {
+ CHECK(mSSL == NULL);
+
+ if (mSSLContext == NULL) {
+ SSL_library_init();
+
+ mSSLContext = SSL_CTX_new(TLSv1_client_method());
+
+ if (mSSLContext == NULL) {
+ LOGE("failed to create SSL context");
+ mState = READY;
+ return ERROR_IO;
+ }
+ }
+
+ mSSL = SSL_new((SSL_CTX *)mSSLContext);
+
+ if (mSSL == NULL) {
+ LOGE("failed to create SSL session");
+
+ mState = READY;
+ return ERROR_IO;
+ }
+
+ int res = SSL_set_fd((SSL *)mSSL, mSocket);
+
+ if (res == 1) {
+ res = SSL_connect((SSL *)mSSL);
+ }
+
+ if (res != 1) {
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+
+ LOGE("failed to connect over SSL");
+ mState = READY;
+
+ return ERROR_IO;
+ }
+ }
+
mState = CONNECTED;
return OK;
@@ -261,6 +315,13 @@
return ERROR_NOT_CONNECTED;
}
+ if (mSSL != NULL) {
+ SSL_shutdown((SSL *)mSSL);
+
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+ }
+
CHECK(mSocket >= 0);
close(mSocket);
mSocket = -1;
@@ -276,7 +337,16 @@
}
while (size > 0) {
- ssize_t n = MySend(mSocket, data, size, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_write((SSL *)mSSL, data, size);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MySend(mSocket, data, size, 0);
+ }
if (n < 0) {
disconnect();
@@ -317,7 +387,17 @@
for (;;) {
char c;
- ssize_t n = MyReceive(mSocket, &c, 1, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, &c, 1);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, &c, 1, 0);
+ }
+
if (n < 0) {
disconnect();
@@ -437,7 +517,16 @@
ssize_t HTTPStream::receive(void *data, size_t size) {
size_t total = 0;
while (total < size) {
- ssize_t n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, (char *)data + total, size - total);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ }
if (n < 0) {
LOGE("recv failed, errno = %d (%s)", (int)n, strerror(-n));
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b11789d..5d6ea7c 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1281,7 +1281,21 @@
initTrackingProgressStatus(params);
sp<MetaData> meta = new MetaData;
+ if (mIsRealTimeRecording && mOwner->numTracks() > 1) {
+ /*
+ * This extra delay of accepting incoming audio/video signals
+ * helps to align a/v start time at the beginning of a recording
+ * session, and it also helps eliminate the "recording" sound for
+ * camcorder applications.
+ *
+ * Ideally, this platform-specific value should be defined
+ * in media_profiles.xml file
+ */
+ startTimeUs += 700000;
+ }
+
meta->setInt64(kKeyTime, startTimeUs);
+
status_t err = mSource->start(meta.get());
if (err != OK) {
mDone = mReachedEOS = true;
@@ -1944,7 +1958,11 @@
((timestampUs * mTimeScale + 500000LL) / 1000000LL -
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
- if (currDurationTicks != lastDurationTicks) {
+ // Force the first sample to have its own stts entry so that
+ // we can adjust its value later to maintain the A/V sync.
+ if (mNumSamples == 3 || currDurationTicks != lastDurationTicks) {
+ LOGV("%s lastDurationUs: %lld us, currDurationTicks: %lld us",
+ mIsAudio? "Audio": "Video", lastDurationUs, currDurationTicks);
addOneSttsTableEntry(sampleCount, lastDurationUs);
sampleCount = 1;
} else {
@@ -1957,6 +1975,8 @@
}
previousSampleSize = sampleSize;
}
+ LOGV("%s timestampUs/lastTimestampUs: %lld/%lld",
+ mIsAudio? "Audio": "Video", timestampUs, lastTimestampUs);
lastDurationUs = timestampUs - lastTimestampUs;
lastDurationTicks = currDurationTicks;
lastTimestampUs = timestampUs;
@@ -2028,7 +2048,16 @@
} else {
++sampleCount; // Count for the last sample
}
- addOneSttsTableEntry(sampleCount, lastDurationUs);
+
+ if (mNumSamples <= 2) {
+ addOneSttsTableEntry(1, lastDurationUs);
+ if (sampleCount - 1 > 0) {
+ addOneSttsTableEntry(sampleCount - 1, lastDurationUs);
+ }
+ } else {
+ addOneSttsTableEntry(sampleCount, lastDurationUs);
+ }
+
mTrackDurationUs += lastDurationUs;
mReachedEOS = true;
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
@@ -2153,6 +2182,9 @@
int32_t mvhdTimeScale = mOwner->getTimeScale();
int64_t trakDurationUs = getDurationUs();
+ // Compensate for small start time difference from different media tracks
+ int64_t trackStartTimeOffsetUs = 0;
+
mOwner->beginBox("trak");
mOwner->beginBox("tkhd");
@@ -2191,26 +2223,8 @@
int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
if (mStartTimestampUs != moovStartTimeUs) {
- mOwner->beginBox("edts");
- mOwner->beginBox("elst");
- mOwner->writeInt32(0); // version=0, flags=0: 32-bit time
- mOwner->writeInt32(2); // never ends with an empty list
-
- // First elst entry: specify the starting time offset
- int64_t offsetUs = mStartTimestampUs - moovStartTimeUs;
- LOGV("OffsetUs: %lld", offsetUs);
- int32_t seg = (offsetUs * mvhdTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(seg); // in mvhd timecale
- mOwner->writeInt32(-1); // starting time offset
- mOwner->writeInt32(1 << 16); // rate = 1.0
-
- // Second elst entry: specify the track duration
- seg = (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(seg); // in mvhd timescale
- mOwner->writeInt32(0);
- mOwner->writeInt32(1 << 16);
- mOwner->endBox();
- mOwner->endBox();
+ CHECK(mStartTimestampUs > moovStartTimeUs);
+ trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
}
mOwner->beginBox("mdia");
@@ -2466,7 +2480,7 @@
mOwner->beginBox("stts");
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt32(mNumSttsTableEntries);
- int64_t prevTimestampUs = 0;
+ int64_t prevTimestampUs = trackStartTimeOffsetUs;
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
it != mSttsTableEntries.end(); ++it) {
mOwner->writeInt32(it->sampleCount);
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index b50af89..0be7261 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -36,6 +36,7 @@
const char *MEDIA_MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";
+const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 08ed206..dbd0829 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -27,6 +27,7 @@
#include "include/DRMExtractor.h"
#include "include/WVMExtractor.h"
#include "include/FLACExtractor.h"
+#include "include/AACExtractor.h"
#include "matroska/MatroskaExtractor.h"
@@ -98,6 +99,8 @@
return new MPEG2TSExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
return new WVMExtractor(source);
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
+ return new AACExtractor(source);
}
return NULL;
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index 0376e1c..e39fab3 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -24,22 +24,30 @@
}
static bool ParseURL(
- const char *url, String8 *host, unsigned *port, String8 *path) {
+ const char *url, String8 *host, unsigned *port,
+ String8 *path, bool *https) {
host->setTo("");
*port = 0;
path->setTo("");
- if (strncasecmp("http://", url, 7)) {
+ size_t hostStart;
+ if (!strncasecmp("http://", url, 7)) {
+ hostStart = 7;
+ *https = false;
+ } else if (!strncasecmp("https://", url, 8)) {
+ hostStart = 8;
+ *https = true;
+ } else {
return false;
}
- const char *slashPos = strchr(&url[7], '/');
+ const char *slashPos = strchr(&url[hostStart], '/');
if (slashPos == NULL) {
- host->setTo(&url[7]);
+ host->setTo(&url[hostStart]);
path->setTo("/");
} else {
- host->setTo(&url[7], slashPos - &url[7]);
+ host->setTo(&url[hostStart], slashPos - &url[hostStart]);
path->setTo(slashPos);
}
@@ -57,7 +65,7 @@
String8 tmp(host->string(), colonOffset);
*host = tmp;
} else {
- *port = 80;
+ *port = (*https) ? 443 : 80;
}
return true;
@@ -66,6 +74,7 @@
NuHTTPDataSource::NuHTTPDataSource()
: mState(DISCONNECTED),
mPort(0),
+ mHTTPS(false),
mOffset(0),
mContentLength(0),
mContentLengthValid(false),
@@ -111,11 +120,12 @@
mUri = uri;
- if (!ParseURL(uri, &host, &port, &path)) {
+ bool https;
+ if (!ParseURL(uri, &host, &port, &path, &https)) {
return ERROR_MALFORMED;
}
- return connect(host, port, path, headers, offset);
+ return connect(host, port, path, https, headers, offset);
}
static bool IsRedirectStatusCode(int httpStatus) {
@@ -125,6 +135,7 @@
status_t NuHTTPDataSource::connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset) {
LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
@@ -132,7 +143,7 @@
bool needsToReconnect = true;
if (mState == CONNECTED && host == mHost && port == mPort
- && offset == mOffset) {
+ && https == mHTTPS && offset == mOffset) {
if (mContentLengthValid && mOffset == mContentLength) {
LOGI("Didn't have to reconnect, old one's still good.");
needsToReconnect = false;
@@ -142,6 +153,7 @@
mHost = host;
mPort = port;
mPath = path;
+ mHTTPS = https;
mHeaders = headers;
status_t err = OK;
@@ -150,7 +162,7 @@
if (needsToReconnect) {
mHTTP.disconnect();
- err = mHTTP.connect(host, port);
+ err = mHTTP.connect(host, port, https);
}
if (err != OK) {
@@ -353,7 +365,7 @@
String8 host = mHost;
String8 path = mPath;
String8 headers = mHeaders;
- status_t err = connect(host, mPort, path, headers, offset);
+ status_t err = connect(host, mPort, path, mHTTPS, headers, offset);
if (err != OK) {
return err;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index fccd68c..5d502e7 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3289,7 +3289,7 @@
}
status_t OMXCodec::stop() {
- CODEC_LOGI("stop mState=%d", mState);
+ CODEC_LOGV("stop mState=%d", mState);
Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index fa12cf0..95cf2d39 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -329,5 +329,52 @@
return foundIDR;
}
+sp<MetaData> MakeAACCodecSpecificData(
+ unsigned profile, unsigned sampling_freq_index,
+ unsigned channel_configuration) {
+ sp<MetaData> meta = new MetaData;
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+ CHECK_LE(sampling_freq_index, 11u);
+ static const int32_t kSamplingFreq[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+ 16000, 12000, 11025, 8000
+ };
+ meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]);
+ meta->setInt32(kKeyChannelCount, channel_configuration);
+
+ static const uint8_t kStaticESDS[] = {
+ 0x03, 22,
+ 0x00, 0x00, // ES_ID
+ 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
+
+ 0x04, 17,
+ 0x40, // Audio ISO/IEC 14496-3
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ 0x05, 2,
+ // AudioSpecificInfo follows
+
+ // oooo offf fccc c000
+ // o - audioObjectType
+ // f - samplingFreqIndex
+ // c - channelConfig
+ };
+ sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
+ memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
+
+ csd->data()[sizeof(kStaticESDS)] =
+ ((profile + 1) << 3) | (sampling_freq_index >> 1);
+
+ csd->data()[sizeof(kStaticESDS) + 1] =
+ ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
+
+ meta->setData(kKeyESDS, 0, csd->data(), csd->size());
+
+ return meta;
+}
+
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 0bed3ca..ee845a3 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -168,18 +168,6 @@
CHECK_GT(mBandwidthItems.size(), 0u);
mBandwidthItems.sort(SortByBandwidth);
-
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.httplive.disable-nuplayer", value, NULL)
- && (!strcasecmp(value, "true") || !strcmp(value, "1"))) {
- // The "legacy" player cannot deal with audio format changes,
- // some streams use different audio encoding parameters for
- // their lowest bandwidth stream.
- if (mBandwidthItems.size() > 1) {
- // XXX Remove the lowest bitrate stream for now...
- mBandwidthItems.removeAt(0);
- }
- }
}
postMonitorQueue();
@@ -201,7 +189,8 @@
if (!strncasecmp(url, "file://", 7)) {
source = new FileSource(url + 7);
- } else if (strncasecmp(url, "http://", 7)) {
+ } else if (strncasecmp(url, "http://", 7)
+ && strncasecmp(url, "https://", 8)) {
return ERROR_UNSUPPORTED;
} else {
{
diff --git a/media/libstagefright/include/AACExtractor.h b/media/libstagefright/include/AACExtractor.h
new file mode 100644
index 0000000..8e5657b
--- /dev/null
+++ b/media/libstagefright/include/AACExtractor.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAC_EXTRACTOR_H_
+
+#define AAC_EXTRACTOR_H_
+
+#include <media/stagefright/MediaExtractor.h>
+
+#include <utils/Vector.h>
+
+namespace android {
+
+struct AMessage;
+class String8;
+
+class AACExtractor : public MediaExtractor {
+public:
+ AACExtractor(const sp<DataSource> &source);
+
+ virtual size_t countTracks();
+ virtual sp<MediaSource> getTrack(size_t index);
+ virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
+
+ virtual sp<MetaData> getMetaData();
+
+protected:
+ virtual ~AACExtractor();
+
+private:
+ sp<DataSource> mDataSource;
+ sp<MetaData> mMeta;
+ status_t mInitCheck;
+
+ Vector<uint64_t> mOffsetVector;
+ int64_t mFrameDurationUs;
+
+ AACExtractor(const AACExtractor &);
+ AACExtractor &operator=(const AACExtractor &);
+};
+
+bool SniffAAC(
+ const sp<DataSource> &source, String8 *mimeType, float *confidence,
+ sp<AMessage> *);
+
+} // namespace android
+
+#endif // AAC_EXTRACTOR_H_
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 98b8c05..1497732 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -43,8 +43,6 @@
class DrmManagerClinet;
class DecryptHandle;
-struct LiveSession;
-
struct AwesomeRenderer : public RefBase {
AwesomeRenderer() {}
@@ -207,8 +205,6 @@
sp<ARTSPController> mRTSPController;
sp<ARTSPController> mConnectingRTSPController;
- sp<LiveSession> mLiveSession;
-
DrmManagerClient *mDrmManagerClient;
DecryptHandle *mDecryptHandle;
@@ -219,7 +215,6 @@
status_t setDataSource_l(const sp<DataSource> &dataSource);
status_t setDataSource_l(const sp<MediaExtractor> &extractor);
void reset_l();
- void partial_reset_l();
status_t seekTo_l(int64_t timeUs);
status_t pause_l(bool at_eos = false);
void initRenderer_l();
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
index 545cd0c..09e6a5f 100644
--- a/media/libstagefright/include/HTTPStream.h
+++ b/media/libstagefright/include/HTTPStream.h
@@ -32,7 +32,7 @@
HTTPStream();
~HTTPStream();
- status_t connect(const char *server, int port = 80);
+ status_t connect(const char *server, int port = -1, bool https = false);
status_t disconnect();
status_t send(const char *data, size_t size);
@@ -71,6 +71,9 @@
KeyedVector<AString, AString> mHeaders;
+ void *mSSLContext;
+ void *mSSL;
+
HTTPStream(const HTTPStream &);
HTTPStream &operator=(const HTTPStream &);
};
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index a99e84a..3918434 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -57,6 +57,7 @@
String8 mHost;
unsigned mPort;
String8 mPath;
+ bool mHTTPS;
String8 mHeaders;
String8 mUri;
@@ -83,6 +84,7 @@
status_t connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset);
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index 3aeb07f..0218755 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -52,6 +52,10 @@
const char *AVCProfileToString(uint8_t profile);
+sp<MetaData> MakeAACCodecSpecificData(
+ unsigned profile, unsigned sampling_freq_index,
+ unsigned channel_configuration);
+
} // namespace android
#endif // AVC_UTILS_H_
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 4335b99..6056739 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -371,21 +371,6 @@
mBuffer->setRange(0, 0);
switch (type) {
- case DISCONTINUITY_HTTPLIVE:
- {
- mQueue.clear(true);
-
- if (mStreamType == 0x1b) {
- // Don't signal discontinuities on audio streams.
- if (mSource != NULL) {
- mSource->queueDiscontinuity(type);
- } else {
- deferDiscontinuity(type);
- }
- }
- break;
- }
-
case DISCONTINUITY_SEEK:
case DISCONTINUITY_FORMATCHANGE:
{
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index ec3be84..455f9d5 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -34,7 +34,6 @@
struct ATSParser : public RefBase {
enum DiscontinuityType {
DISCONTINUITY_NONE,
- DISCONTINUITY_HTTPLIVE,
DISCONTINUITY_SEEK,
DISCONTINUITY_FORMATCHANGE
};
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 73efdfe..dcaf9f7 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -341,54 +341,6 @@
return timeUs;
}
-// static
-sp<MetaData> ElementaryStreamQueue::MakeAACCodecSpecificData(
- unsigned profile, unsigned sampling_freq_index,
- unsigned channel_configuration) {
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-
- CHECK_LE(sampling_freq_index, 11u);
- static const int32_t kSamplingFreq[] = {
- 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
- 16000, 12000, 11025, 8000
- };
- meta->setInt32(kKeySampleRate, kSamplingFreq[sampling_freq_index]);
- meta->setInt32(kKeyChannelCount, channel_configuration);
-
- static const uint8_t kStaticESDS[] = {
- 0x03, 22,
- 0x00, 0x00, // ES_ID
- 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- 0x04, 17,
- 0x40, // Audio ISO/IEC 14496-3
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x05, 2,
- // AudioSpecificInfo follows
-
- // oooo offf fccc c000
- // o - audioObjectType
- // f - samplingFreqIndex
- // c - channelConfig
- };
- sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
- memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
-
- csd->data()[sizeof(kStaticESDS)] =
- ((profile + 1) << 3) | (sampling_freq_index >> 1);
-
- csd->data()[sizeof(kStaticESDS) + 1] =
- ((sampling_freq_index << 7) & 0x80) | (channel_configuration << 3);
-
- meta->setData(kKeyESDS, 0, csd->data(), csd->size());
-
- return meta;
-}
-
struct NALPosition {
size_t nalOffset;
size_t nalSize;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 5b7957e..d081995 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -61,10 +61,6 @@
// returns its timestamp in us (or -1 if no time information).
int64_t fetchTimestamp(size_t size);
- static sp<MetaData> MakeAACCodecSpecificData(
- unsigned profile, unsigned sampling_freq_index,
- unsigned channel_configuration);
-
DISALLOW_EVIL_CONSTRUCTORS(ElementaryStreamQueue);
};
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index a1f0796..dfec47f 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -202,20 +202,13 @@
LOGI("haveAudio=%d, haveVideo=%d", haveAudio, haveVideo);
}
-static bool isDiscontinuity(const uint8_t *data, ssize_t size) {
- return size == 188 && data[0] == 0x00;
-}
-
status_t MPEG2TSExtractor::feedMore() {
Mutex::Autolock autoLock(mLock);
uint8_t packet[kTSPacketSize];
ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
- if (isDiscontinuity(packet, n)) {
- LOGI("XXX discontinuity detected");
- mParser->signalDiscontinuity(ATSParser::DISCONTINUITY_HTTPLIVE);
- } else if (n < (ssize_t)kTSPacketSize) {
+ if (n < (ssize_t)kTSPacketSize) {
return (n < 0) ? (status_t)n : ERROR_END_OF_STREAM;
} else {
mParser->feedTSPacket(packet, kTSPacketSize);
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 13988cd..9f6bd29 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -104,7 +104,7 @@
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0),
mAccessUnitDamaged(false) {
- mIsGeneric = desc.startsWith("mpeg4-generic/");
+ mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
if (mIsGeneric) {
AString value;
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index f0b858d..679dcab 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -637,7 +637,7 @@
mFormat->setInt32(kKeyWidth, width);
mFormat->setInt32(kKeyHeight, height);
- } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+ } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
AString val;
if (!GetAttribute(params.c_str(), "mode", &val)
|| (strcasecmp(val.c_str(), "AAC-lbr")
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 601f569..47de4e09 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -123,7 +123,7 @@
struct sockaddr_in addr;
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(*rtpSocket,
@@ -340,6 +340,8 @@
}
status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
+ LOGV("receiving %s", receiveRTP ? "RTP" : "RTCP");
+
CHECK(!s->mIsInjected);
sp<ABuffer> buffer = new ABuffer(65536);
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 893a387..84c666f 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -67,7 +67,7 @@
} else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
} else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
- || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+ || !strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
mIssueFIRRequests = true;
} else {
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index e936923..0740515 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -545,6 +545,10 @@
return buffer;
}
+static bool IsRTSPVersion(const AString &s) {
+ return s == "RTSP/1.0";
+}
+
bool ARTSPConnection::receiveRTSPReponse() {
AString statusLine;
@@ -584,13 +588,27 @@
return false;
}
- AString statusCodeStr(
- response->mStatusLine, space1 + 1, space2 - space1 - 1);
+ bool isRequest = false;
- if (!ParseSingleUnsignedLong(
- statusCodeStr.c_str(), &response->mStatusCode)
- || response->mStatusCode < 100 || response->mStatusCode > 999) {
- return false;
+ if (!IsRTSPVersion(AString(response->mStatusLine, 0, space1))) {
+ CHECK(IsRTSPVersion(
+ AString(
+ response->mStatusLine,
+ space2 + 1,
+ response->mStatusLine.size() - space2 - 1)));
+
+ isRequest = true;
+
+ response->mStatusCode = 0;
+ } else {
+ AString statusCodeStr(
+ response->mStatusLine, space1 + 1, space2 - space1 - 1);
+
+ if (!ParseSingleUnsignedLong(
+ statusCodeStr.c_str(), &response->mStatusCode)
+ || response->mStatusCode < 100 || response->mStatusCode > 999) {
+ return false;
+ }
}
AString line;
@@ -680,7 +698,63 @@
}
}
- return notifyResponseListener(response);
+ return isRequest
+ ? handleServerRequest(response)
+ : notifyResponseListener(response);
+}
+
+bool ARTSPConnection::handleServerRequest(const sp<ARTSPResponse> &request) {
+ // Implementation of server->client requests is optional for all methods
+ // but we do need to respond, even if it's just to say that we don't
+ // support the method.
+
+ ssize_t space1 = request->mStatusLine.find(" ");
+ CHECK_GE(space1, 0);
+
+ AString response;
+ response.append("RTSP/1.0 501 Not Implemented\r\n");
+
+ ssize_t i = request->mHeaders.indexOfKey("cseq");
+
+ if (i >= 0) {
+ AString value = request->mHeaders.valueAt(i);
+
+ unsigned long cseq;
+ if (!ParseSingleUnsignedLong(value.c_str(), &cseq)) {
+ return false;
+ }
+
+ response.append("CSeq: ");
+ response.append(cseq);
+ response.append("\r\n");
+ }
+
+ response.append("\r\n");
+
+ size_t numBytesSent = 0;
+ while (numBytesSent < response.size()) {
+ ssize_t n =
+ send(mSocket, response.c_str() + numBytesSent,
+ response.size() - numBytesSent, 0);
+
+ if (n == 0) {
+ // Server closed the connection.
+ LOGE("Server unexpectedly closed the connection.");
+
+ return false;
+ } else if (n < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+
+ LOGE("Error sending rtsp response.");
+ return false;
+ }
+
+ numBytesSent += (size_t)n;
+ }
+
+ return true;
}
// static
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 19be2a6..0fecf3c 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -109,6 +109,8 @@
status_t findPendingRequest(
const sp<ARTSPResponse> &response, ssize_t *index) const;
+ bool handleServerRequest(const sp<ARTSPResponse> &request);
+
static bool ParseSingleUnsignedLong(
const char *from, unsigned long *x);
diff --git a/media/libstagefright/rtsp/ASessionDescription.cpp b/media/libstagefright/rtsp/ASessionDescription.cpp
index 3e710dc..f03f7a2 100644
--- a/media/libstagefright/rtsp/ASessionDescription.cpp
+++ b/media/libstagefright/rtsp/ASessionDescription.cpp
@@ -71,6 +71,11 @@
line.setTo(desc, i, eolPos - i);
}
+ if (line.empty()) {
+ i = eolPos + 1;
+ continue;
+ }
+
if (line.size() < 2 || line.c_str()[1] != '=') {
return false;
}
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index ba7c1b2..d15d9c5 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -38,6 +38,7 @@
#include <arpa/inet.h>
#include <sys/socket.h>
+#include <netdb.h>
// If no access units are received within 5 secs, assume that the rtp
// stream has ended and signal end of stream.
@@ -121,9 +122,10 @@
// want to transmit user/pass in cleartext.
AString host, path, user, pass;
unsigned port;
- if (ARTSPConnection::ParseURL(
- mSessionURL.c_str(), &host, &port, &path, &user, &pass)
- && user.size() > 0) {
+ CHECK(ARTSPConnection::ParseURL(
+ mSessionURL.c_str(), &host, &port, &path, &user, &pass));
+
+ if (user.size() > 0) {
mSessionURL.clear();
mSessionURL.append("rtsp://");
mSessionURL.append(host);
@@ -133,6 +135,8 @@
LOGI("rewritten session url: '%s'", mSessionURL.c_str());
}
+
+ mSessionHost = host;
}
void connect(const sp<AMessage> &doneMsg) {
@@ -248,34 +252,64 @@
// In case we're behind NAT, fire off two UDP packets to the remote
// rtp/rtcp ports to poke a hole into the firewall for future incoming
// packets. We're going to send an RR/SDES RTCP packet to both of them.
- void pokeAHole(int rtpSocket, int rtcpSocket, const AString &transport) {
+ bool pokeAHole(int rtpSocket, int rtcpSocket, const AString &transport) {
+ struct sockaddr_in addr;
+ memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
+ addr.sin_family = AF_INET;
+
AString source;
AString server_port;
if (!GetAttribute(transport.c_str(),
"source",
- &source)
- || !GetAttribute(transport.c_str(),
+ &source)) {
+ LOGW("Missing 'source' field in Transport response. Using "
+ "RTSP endpoint address.");
+
+ struct hostent *ent = gethostbyname(mSessionHost.c_str());
+ if (ent == NULL) {
+ LOGE("Failed to look up address of session host '%s'",
+ mSessionHost.c_str());
+
+ return false;
+ }
+
+ addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
+ } else {
+ addr.sin_addr.s_addr = inet_addr(source.c_str());
+ }
+
+ if (!GetAttribute(transport.c_str(),
"server_port",
&server_port)) {
- return;
+ LOGI("Missing 'server_port' field in Transport response.");
+ return false;
}
int rtpPort, rtcpPort;
if (sscanf(server_port.c_str(), "%d-%d", &rtpPort, &rtcpPort) != 2
|| rtpPort <= 0 || rtpPort > 65535
|| rtcpPort <=0 || rtcpPort > 65535
- || rtcpPort != rtpPort + 1
- || (rtpPort & 1) != 0) {
- return;
+ || rtcpPort != rtpPort + 1) {
+ LOGE("Server picked invalid RTP/RTCP port pair %s,"
+ " RTP port must be even, RTCP port must be one higher.",
+ server_port.c_str());
+
+ return false;
}
- struct sockaddr_in addr;
- memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr(source.c_str());
+ if (rtpPort & 1) {
+ LOGW("Server picked an odd RTP port, it should've picked an "
+ "even one, we'll let it pass for now, but this may break "
+ "in the future.");
+ }
if (addr.sin_addr.s_addr == INADDR_NONE) {
- return;
+ return true;
+ }
+
+ if (IN_LOOPBACK(ntohl(addr.sin_addr.s_addr))) {
+ // No firewalls to traverse on the loopback interface.
+ return true;
}
// Make up an RR/SDES RTCP packet.
@@ -289,16 +323,26 @@
ssize_t n = sendto(
rtpSocket, buf->data(), buf->size(), 0,
(const sockaddr *)&addr, sizeof(addr));
- CHECK_EQ(n, (ssize_t)buf->size());
+
+ if (n < (ssize_t)buf->size()) {
+ LOGE("failed to poke a hole for RTP packets");
+ return false;
+ }
addr.sin_port = htons(rtcpPort);
n = sendto(
rtcpSocket, buf->data(), buf->size(), 0,
(const sockaddr *)&addr, sizeof(addr));
- CHECK_EQ(n, (ssize_t)buf->size());
+
+ if (n < (ssize_t)buf->size()) {
+ LOGE("failed to poke a hole for RTCP packets");
+ return false;
+ }
LOGV("successfully poked holes.");
+
+ return true;
}
virtual void onMessageReceived(const sp<AMessage> &msg) {
@@ -381,6 +425,7 @@
response->mContent->size());
if (!mSessionDesc->isValid()) {
+ LOGE("Failed to parse session description.");
result = ERROR_MALFORMED;
} else {
ssize_t i = response->mHeaders.indexOfKey("content-base");
@@ -395,6 +440,25 @@
}
}
+ if (!mBaseURL.startsWith("rtsp://")) {
+ // Some misbehaving servers specify a relative
+ // URL in one of the locations above, combine
+ // it with the absolute session URL to get
+ // something usable...
+
+ LOGW("Server specified a non-absolute base URL"
+ ", combining it with the session URL to "
+ "get something usable...");
+
+ AString tmp;
+ CHECK(MakeURL(
+ mSessionURL.c_str(),
+ mBaseURL.c_str(),
+ &tmp));
+
+ mBaseURL = tmp;
+ }
+
CHECK_GT(mSessionDesc->countTracks(), 1u);
setupTrack(1);
}
@@ -455,9 +519,12 @@
if (!track->mUsingInterleavedTCP) {
AString transport = response->mHeaders.valueAt(i);
- pokeAHole(track->mRTPSocket,
- track->mRTCPSocket,
- transport);
+ // We are going to continue even if we were
+ // unable to poke a hole into the firewall...
+ pokeAHole(
+ track->mRTPSocket,
+ track->mRTCPSocket,
+ transport);
}
mRTPConn->addStream(
@@ -853,17 +920,16 @@
case 'tiou':
{
if (!mReceivedFirstRTCPPacket) {
- if (mTryFakeRTCP) {
- LOGW("Never received any data, disconnecting.");
- (new AMessage('abor', id()))->post();
- } else if (mTryTCPInterleaving && mReceivedFirstRTPPacket) {
+ if (mReceivedFirstRTPPacket && !mTryFakeRTCP) {
LOGW("We received RTP packets but no RTCP packets, "
"using fake timestamps.");
mTryFakeRTCP = true;
mReceivedFirstRTCPPacket = true;
- } else {
+
+ fakeTimestamps();
+ } else if (!mReceivedFirstRTPPacket && !mTryTCPInterleaving) {
LOGW("Never received any data, switching transports.");
mTryTCPInterleaving = true;
@@ -871,6 +937,9 @@
sp<AMessage> msg = new AMessage('abor', id());
msg->setInt32("reconnect", true);
msg->post();
+ } else {
+ LOGW("Never received any data, disconnecting.");
+ (new AMessage('abor', id()))->post();
}
}
break;
@@ -1016,6 +1085,7 @@
sp<ASessionDescription> mSessionDesc;
AString mOriginalSessionURL; // This one still has user:pass@
AString mSessionURL;
+ AString mSessionHost;
AString mBaseURL;
AString mSessionID;
bool mSetupTracksSuccessful;
@@ -1158,6 +1228,12 @@
return true;
}
+ void fakeTimestamps() {
+ for (size_t i = 0; i < mTracks.size(); ++i) {
+ onTimeUpdate(i, 0, 0ll);
+ }
+ }
+
void onTimeUpdate(int32_t trackIndex, uint32_t rtpTime, uint64_t ntpTime) {
LOGV("onTimeUpdate track %d, rtpTime = 0x%08x, ntpTime = 0x%016llx",
trackIndex, rtpTime, ntpTime);
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index fb1b073..4ea8849 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -38,6 +38,7 @@
namespace android {
+#if 0
static bool isMtpDevice(uint16_t vendor, uint16_t product) {
// Sandisk Sansa Fuze
if (vendor == 0x0781 && product == 0x74c2)
@@ -47,6 +48,7 @@
return true;
return false;
}
+#endif
MtpDevice* MtpDevice::open(const char* deviceName, int fd) {
struct usb_device *device = usb_device_new(deviceName, fd);
@@ -91,7 +93,9 @@
LOGD("Found MTP device: \"%s\" \"%s\"\n", manufacturerName, productName);
free(manufacturerName);
free(productName);
- } else {
+ }
+#if 0
+ else {
// look for special cased devices based on vendor/product ID
// we are doing this mainly for testing purposes
uint16_t vendor = usb_device_get_vendor_id(device);
@@ -119,7 +123,7 @@
printf("no MTP string\n");
}
}
-
+#endif
// if we got here, then we have a likely MTP or PTP device
// interface should be followed by three endpoints
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index c9d2628b..dd5e026 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -22,6 +22,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
<application>
<uses-library android:name="android.test.runner" />
<activity android:label="@string/app_name"
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
index eaaa798..988b229 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
@@ -17,7 +17,8 @@
package com.android.mediaframeworktest;
import com.android.mediaframeworktest.performance.MediaPlayerPerformance;
-
+/*Video Editor performance Test cases*/
+import com.android.mediaframeworktest.performance.VideoEditorPerformance;
import junit.framework.TestSuite;
import android.test.InstrumentationTestRunner;
@@ -26,7 +27,7 @@
/**
* Instrumentation Test Runner for all MediaPlayer tests.
- *
+ *
* Running all tests:
*
* adb shell am instrument \
@@ -40,6 +41,8 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerPerformance.class);
+ /*Video Editor performance Test cases*/
+ suite.addTestSuite(VideoEditorPerformance.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
index 41f0e22..79fd2cb 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
@@ -24,6 +24,7 @@
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
+import android.os.PowerManager;
import android.provider.Downloads;
import android.util.Log;
import android.util.Log;
@@ -48,7 +49,7 @@
import java.net.InetAddress;
-public class MediaFrameworkTest extends Activity {
+public class MediaFrameworkTest extends Activity implements SurfaceHolder.Callback {
//public static Surface video_sf;
public static SurfaceView mSurfaceView;
@@ -63,11 +64,13 @@
public static Bitmap mDestBitmap;
public static ImageView mOverlayView;
-
+ private SurfaceHolder mSurfaceHolder = null;
+ private String TAG = "MediaFrameworkTest";
+ private PowerManager.WakeLock mWakeLock = null;
+
public MediaFrameworkTest() {
}
-
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
@@ -76,7 +79,9 @@
mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
mOverlayView = (ImageView)findViewById(R.id.overlay_layer);
ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
- mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ mSurfaceHolder = mSurfaceView.getHolder();
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ mSurfaceHolder.addCallback(this);
//Get the midi fd
midiafd = this.getResources().openRawResourceFd(R.raw.testmidi);
@@ -86,8 +91,31 @@
mOverlayView.setLayoutParams(lp);
mDestBitmap = Bitmap.createBitmap((int)640, (int)480, Bitmap.Config.ARGB_8888);
mOverlayView.setImageBitmap(mDestBitmap);
+
+ //Acquire the full wake lock to keep the device up
+ PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MediaFrameworkTest");
+ mWakeLock.acquire();
}
-
+
+ public void onStop(Bundle icicle) {
+ mWakeLock.release();
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ //Can do nothing in here. The test case will fail if the surface destroyed.
+ Log.v(TAG, "Test application surface destroyed");
+ mSurfaceHolder = null;
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ //Do nothing in here. Just print out the log
+ Log.v(TAG, "Test application surface changed");
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ }
+
public void startPlayback(String filename){
String mimetype = "audio/mpeg";
Uri path = Uri.parse(filename);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
index 5438061..0cd784c 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
@@ -19,6 +19,8 @@
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.MediaPlayerStressTest;
+/** Import for Video Editor Stress Test cases*/
+import com.android.mediaframeworktest.stress.VideoEditorStressTest;
import junit.framework.TestSuite;
@@ -28,6 +30,8 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerStressTest.class);
+ /** Video Editor Stress Test cases*/
+ suite.addTestSuite(VideoEditorStressTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
index cad7e53..e84f762 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -60,11 +60,11 @@
private static boolean onPrepareSuccess = false;
public static boolean onCompleteSuccess = false;
public static boolean mPlaybackError = false;
- public static boolean mIsMediaInfoUnknown = false;
- public static boolean mIsMediaInfoVideoTrackLagging = false;
- public static boolean mIsMediaInfoBadInterleaving = false;
- public static boolean mIsMediaInfoNotSeekable = false;
- public static boolean mIsMediaInfoMetdataUpdate = false;
+ public static int mMediaInfoUnknownCount = 0;
+ public static int mMediaInfoVideoTrackLaggingCount = 0;
+ public static int mMediaInfoBadInterleavingCount = 0;
+ public static int mMediaInfoNotSeekableCount = 0;
+ public static int mMediaInfoMetdataUpdateCount = 0;
public static String printCpuInfo(){
String cm = "dumpsys cpuinfo";
@@ -765,19 +765,19 @@
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what){
case MediaPlayer.MEDIA_INFO_UNKNOWN:
- mIsMediaInfoUnknown = true;
+ mMediaInfoUnknownCount++;
break;
case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
- mIsMediaInfoVideoTrackLagging = true;
+ mMediaInfoVideoTrackLaggingCount++;
break;
case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
- mIsMediaInfoBadInterleaving = true;
+ mMediaInfoBadInterleavingCount++;
break;
case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
- mIsMediaInfoNotSeekable = true;
+ mMediaInfoNotSeekableCount++;
break;
case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
- mIsMediaInfoMetdataUpdate = true;
+ mMediaInfoMetdataUpdateCount++;
break;
}
return true;
@@ -791,11 +791,11 @@
int nextPosition = 0;
int waittime = 0;
onCompleteSuccess = false;
- mIsMediaInfoUnknown = false;
- mIsMediaInfoVideoTrackLagging = false;
- mIsMediaInfoBadInterleaving = false;
- mIsMediaInfoNotSeekable = false;
- mIsMediaInfoMetdataUpdate = false;
+ mMediaInfoUnknownCount = 0;
+ mMediaInfoVideoTrackLaggingCount = 0;
+ mMediaInfoBadInterleavingCount = 0;
+ mMediaInfoNotSeekableCount = 0;
+ mMediaInfoMetdataUpdateCount = 0;
mPlaybackError = false;
String testResult;
@@ -811,6 +811,7 @@
try {
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mOnErrorListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
Log.v(TAG, "playMediaSamples: sample file name " + filePath);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
index bd0a838..9a7f4f2 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
@@ -95,7 +95,7 @@
private boolean previewStop;
/* Minimum waiting time for Semaphore to wait for release */
- private final long minWaitingTime = 1000;
+ private final long minWaitingTime = 3000;
// Declares the annotation for Preview Test Cases
public @interface Preview {
@@ -473,8 +473,8 @@
mVideoEditorHelper.checkProgressCBValues(progressValues);
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
-
- long waitingTime = minWaitingTime + 10000;
+ /* As transition takes more time buffer of 10 sec is added */
+ long waitingTime = minWaitingTime + 10000 + 10000;
blockTillPreviewCompletes.acquire();
try {
@@ -691,31 +691,34 @@
long waitingTime = minWaitingTime + mVideoEditor.getDuration();
+
blockTillPreviewCompletes.acquire();
+ final String fileName = mVideoEditor.getPath() + "\test.3gp";
+ final int height = MediaProperties.HEIGHT_480;
+ final int bitrate = MediaProperties.BITRATE_512K;
+
+ try {
+ mVideoEditor.export(fileName, height, bitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName,int progress) {
+
+ }
+ });
+ } catch (IOException e) {
+ assertTrue("UnExpected Error in Export" +
+ e.toString(), false);
+ }
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
try {
+
mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
new PreviewProgressListener() {
- final String fileName = mVideoEditor.getPath() + "\test.3gp";
- final int height = MediaProperties.HEIGHT_360;
- final int bitrate = MediaProperties.BITRATE_512K;
+
public void onProgress(VideoEditor videoEditor, long timeMs,
OverlayData overlayData) {
- if (timeMs >= 10000)
- try {
- videoEditor.export(fileName, height, bitrate,
- new ExportProgressListener() {
- public void onProgress(VideoEditor ve,
- String outFileName,int progress) {
-
- }
- });
- } catch (IOException e) {
- assertTrue("UnExpected Error in Export" +
- e.toString(), false);
- }
}
public void onStart(VideoEditor videoEditor) {
setPreviewStart();
@@ -725,10 +728,10 @@
blockTillPreviewCompletes.release();
}
});
+
} catch (Exception e) {
blockTillPreviewCompletes.release();
}
-
blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
mVideoEditor.stopPreview();
assertTrue("Preview Failed to start", previewStart);
@@ -837,31 +840,7 @@
mVideoEditor.renderPreviewFrame(surfaceHolder, 7000,
overlayData1));
- long waitingTime = minWaitingTime + (mVideoEditor.getDuration() - 5000);
-
- blockTillPreviewCompletes.acquire();
- try {
- mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
- new PreviewProgressListener() {
- public void onProgress(VideoEditor videoEditor, long timeMs,
- OverlayData overlayData) {
- }
- public void onStart(VideoEditor videoEditor) {
- setPreviewStart();
- }
- public void onStop(VideoEditor videoEditor) {
- setPreviewStop();
- blockTillPreviewCompletes.release();
- }
- });
- } catch (Exception e) {
- blockTillPreviewCompletes.release();
- }
- blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
- mVideoEditor.stopPreview();
- assertTrue("Preview Failed to start", previewStart);
- assertTrue("Preview Failed to stop", previewStop);
- blockTillPreviewCompletes.release();
+ validatePreviewProgress(5000, -1, false, mVideoEditor.getDuration());
}
/**
@@ -1142,20 +1121,19 @@
duration = mVideoEditor.getDuration();
/* RenderPreviewFrame returns -1 to indicate last frame */
try {
- assertEquals("Render preview Frame at item duration", -1,
- mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
- overlayData1));
- } catch ( Exception e) {
- assertTrue (" Render Preview Frame without generate", false);
- }
- duration = mVideoEditor.getDuration() + 1000;
- try {
mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
overlayData1);
} catch ( IllegalStateException e) {
flagForException = true;
}
+ assertTrue (" Render Preview Frame without generate", flagForException);
+ duration = mVideoEditor.getDuration() + 1000;
+ try {
+ mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
+ overlayData1);
+ } catch ( IllegalArgumentException e) {
+ flagForException = true;
+ }
assertTrue (" Preview time greater than duration", flagForException);
}
-
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
new file mode 100644
index 0000000..4481d00
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.mediaframeworktest.performance;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorPerformance extends
+ ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorPerformance.txt";
+
+ public VideoEditorPerformance() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String testCaseName, String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write(testCaseName + "\n\t");
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.write("\n\n");
+ output.close();
+ }
+
+ private final int NUM_OF_ITERATIONS=20;
+
+ private float calculateTimeTaken(long beginTime, int numIterations)
+ throws Exception {
+ final long duration2 = SystemClock.uptimeMillis();
+ final long durationToCreateMediaItem = (duration2 - beginTime);
+ final float timeTaken1 = (float)durationToCreateMediaItem *
+ 1.0f/(float)numIterations;
+ return (timeTaken1);
+ }
+
+ private void createVideoItems(MediaVideoItem[] mediaVideoItem,
+ String videoItemFileName, int renderingMode, int startTime, int endTime) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(startTime, endTime);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not create an object of Video Item with file name = "
+ + videoItemFileName + "------ID:m" + i + " Issue = "
+ + e1.toString(), false);
+ }
+ }
+ }
+
+ private void addVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not add an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void removeVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mediaVideoItem[i].getId());
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not Remove an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void createImageItems(MediaImageItem[] mIi,
+ String imageItemFileName, int renderingMode, int duration) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mIi[i] = new MediaImageItem(mVideoEditor, "m" + i,
+ imageItemFileName, duration, renderingMode);
+ } catch (Exception e1) {
+ assertTrue( " Cannot create Image Item", false);
+ }
+ }
+ }
+
+ private void addImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mIi[i]);
+ } catch (Exception e1) {
+ assertTrue("Cannot add Image item", false);
+ }
+ }
+ }
+
+ private void removeImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mIi[i].getId());
+ } catch (Exception e1) {
+ assertTrue("Cannot remove image item", false);
+ }
+ }
+ }
+ /**
+ * To test the performance of adding and removing the video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_001
+ @LargeTest
+ public void testPerformanceAddRemoveVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 5000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+ long startTime = 0;
+
+ /** Time Take for creation of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ createVideoItems(mediaVideoItem, videoItemFileName, renderingMode,
+ videoItemStartTime, videoItemEndTime);
+
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Video Item\t" +
+ timeTaken;
+
+ /** Time Take for Addition of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ addVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to Add Media Video Item\t"
+ + timeTaken;
+
+ /** Time Take for Removal of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ removeVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Video Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the image media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_002
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveImageItem (in mSec)",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_003
+ @LargeTest
+ public void testPerformanceAddRemoveTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 20000;
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime2 = 0;
+ final int videoItemEndTime2 = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final String[] loggingInfo = new String[3];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[(NUM_OF_ITERATIONS *10) + 1];
+
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i+=2) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName1, renderingMode);
+ mediaVideoItem[i+1] = new MediaVideoItem(mVideoEditor,
+ "m" + (i+1), videoItemFileName2, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ mediaVideoItem[i+1].setExtractBoundaries(videoItemStartTime2,
+ videoItemEndTime2);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Object Item with file name = "
+ + e1.toString(), false);
+ }
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ mVideoEditor.addMediaItem(mediaVideoItem[i+1]);
+ }
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)] = new MediaVideoItem(mVideoEditor,
+ "m" + (NUM_OF_ITERATIONS *10), videoItemFileName1, renderingMode);
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)].setExtractBoundaries(
+ videoItemStartTime1, videoItemEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem[(NUM_OF_ITERATIONS *10)]);
+ final TransitionCrossfade tranCrossfade[] =
+ new TransitionCrossfade[(NUM_OF_ITERATIONS *10)];
+
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ tranCrossfade[i] = new TransitionCrossfade("transition" + i,
+ mediaVideoItem[i], mediaVideoItem[i+1], transitionDuration,
+ transitionBehavior);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[0] = "Time taken to Create CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ mVideoEditor.addTransition(tranCrossfade[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[1] = "\n\tTime taken to add CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ assertEquals("Removing Transitions", tranCrossfade[i], mVideoEditor
+ .removeTransition(tranCrossfade[i].getId()));
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveTransition (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test performance of Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_004
+ @LargeTest
+ public void testPerformanceExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int outHeight = MediaProperties.HEIGHT_480;
+ final int outBitrate = MediaProperties.BITRATE_256K;
+ final int outVcodec = MediaProperties.VCODEC_H264BP;
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper
+ .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_12Mbps_AACLC_44.1khz_64kbps_s_1_17.mp4";
+ final String imageItemFileName1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_32kbps_m_1_17.3gp";
+ final String imageItemFileName2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String overlayFile = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
+ final String audioTrackFilename = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", imageItemFileName1, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName2, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaVideoItem mediaItem5 = new MediaVideoItem(mVideoEditor,
+ "m5", videoItemFileName3, renderingMode);
+ mediaItem5.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem5);
+ /**
+ * 7.Add TransitionAlpha, Apply this Transition as Begin for Media Item 1
+ * with duration = 2 sec behavior = BEHAVIOR_LINEAR, mask file name =
+ * TransitionSpiral_QVGA.jpg , blending percent = 50%, invert = true;
+ * */
+ final TransitionAlpha transition1 =
+ mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
+ 2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
+ mVideoEditor.addTransition(transition1);
+
+ /**
+ * 8.Add Transition Sliding between MediaItem 2 and 3 ,
+ * Sliding Direction = DIRECTION_RIGHT_OUT_LEFT_IN,
+ * behavior = BEHAVIOR_MIDDLE_FAST and duration = 4sec
+ * */
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transition2", mediaItem2,
+ mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
+ mVideoEditor.addTransition(transition2And3);
+
+ /**
+ * 9.Add Transition Crossfade between Media Item 3 and 4,
+ * behavior = BEHAVIOR_MIDDLE_SLOW, duration = 3.5 sec
+ * */
+ final TransitionCrossfade transition3And4 =
+ mVideoEditorHelper.createTCrossFade("transition3", mediaItem3,
+ mediaItem4, 3500, Transition.BEHAVIOR_MIDDLE_SLOW);
+ mVideoEditor.addTransition(transition3And4);
+
+ /**
+ * 10.Add Transition Fadeblack between Media Item 4 and 5,
+ * behavior = BEHAVIOR_SPEED_DOWN, duration = 3.5 sec
+ * */
+ final TransitionFadeBlack transition4And5 =
+ mVideoEditorHelper.createTFadeBlack("transition4", mediaItem4,
+ mediaItem5, 3500, Transition.BEHAVIOR_SPEED_DOWN);
+ mVideoEditor.addTransition(transition4And5);
+
+ /**
+ * 11.Add Effect 1 type="TYPE_SEPIA" to the MediaItem 1,
+ * start time=1sec and duration =4secs
+ * */
+ final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
+ mediaItem1, "effect1", 1000, 4000, EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ /**
+ * 12.Add Overlay 1 to the MediaItem 3: Frame Overlay with start time = 1 sec
+ * duration = 4 sec with item = IMG_640x480_Overlay1.png
+ * */
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFile, 640,
+ 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem3, "overlay",
+ mBitmap, 1000, 4000);
+ mediaItem3.addOverlay(overlayFrame);
+ /**
+ * 13.Add Effect 2 type="TYPE_NEGATIVE" to the MediaItem 2,
+ * start time=8sec and duration =2secs
+ * */
+ final EffectColor effectColor2 = mVideoEditorHelper.createEffectItem(
+ mediaItem2, "effect2", 8000, 2000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor2);
+ /**
+ * 14.Add Effect 3 type="TYPE_COLOR" to the MediaItem 3, color param = "PINK",
+ * start time=5 sec and duration =3secs
+ * */
+ final EffectColor effectColor3 = mVideoEditorHelper.createEffectItem(
+ mediaItem3, "effect3", 5000, 3000, EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem3.addEffect(effectColor3);
+ /**
+ * 15.Add Effect 4 type="TYPE_FIFTIES" to the MediaItem 4,
+ * start time=2 sec and duration =1secs
+ * */
+ final EffectColor effectColor4 = mVideoEditorHelper.createEffectItem(
+ mediaItem4, "effect4", 2000, 1000, EffectColor.TYPE_FIFTIES, 0);
+ mediaItem4.addEffect(effectColor4);
+ /**
+ * 16.Add KenBurnsEffect for MediaItem 4 with
+ * duration = 3 sec and startTime = 4 sec
+ * StartRect
+ * left = org_height/3 ; top = org_width/3
+ * bottom = org_width/2 ; right = org_height/2
+ * EndRect
+ * left = 0 ; top = 0
+ * bottom = org_height; right = org_width
+ * */
+
+ final Rect startRect = new Rect((mediaItem4.getHeight() / 3),
+ (mediaItem4.getWidth() / 3), (mediaItem4.getHeight() / 2),
+ (mediaItem4.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem4.getWidth(),
+ mediaItem4.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem4, "KBOnM2", startRect, endRect,4000 , 3000);
+ mediaItem4.addEffect(kbEffectOnMediaItem);
+
+ /** 17.Add Audio Track,Set extract boundaries o to 10 sec.
+ * */
+ final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
+ mVideoEditor, "audioTrack", audioTrackFilename);
+ mVideoEditor.addAudioTrack(audioTrack);
+ /** 18.Enable Looping for Audio Track.
+ * */
+ audioTrack.enableLoop();
+ float timeTaken = 0.0f;
+ final long beginTime = SystemClock.uptimeMillis();
+ try {
+ mVideoEditor.export(outFilename, outHeight, outBitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName, int progress) {
+ }
+ });
+ } catch (Exception e) {
+ assertTrue("Error in Export" + e.toString(), false);
+ }
+ mVideoEditorHelper.checkDeleteExistingFile(outFilename);
+
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken to do ONE export of storyboard duration\t"
+ + mVideoEditor.getDuration() + " is :\t" + timeTaken;
+
+ writeTimingInfo("testPerformanceExport (in mSec)", loggingInfo);
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ }
+
+
+ /**
+ * To test the performance of thumbnail extraction
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_005
+ @LargeTest
+ public void testPerformanceThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime,
+ videoItemEndTime);
+
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ mediaVideoItem.getThumbnail(mediaVideoItem.getWidth() / 2,
+ mediaVideoItem.getHeight() / 2, i);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Duration taken to get Video Thumbnails\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceThumbnailVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the overlay to media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_006
+ @LargeTest
+ public void testPerformanceOverlayVideoItem() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String overlayFilename = INPUT_FILE_PATH
+ + "IMG_640x480_Overlay1.png";
+ final int overlayStartTime = 1000;
+ final int overlayDuration = 5000;
+
+ final String[] loggingInfo = new String[2];
+ MediaVideoItem mediaVideoItem = null;
+
+ try {
+ mediaVideoItem = new MediaVideoItem(mVideoEditor, "m0",
+ videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ final OverlayFrame overlayFrame[] = new OverlayFrame[NUM_OF_ITERATIONS];
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFilename,
+ 640, 480);
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ overlayFrame[i] = new OverlayFrame(mediaVideoItem, "overlay" + i,
+ mBitmap, overlayStartTime, overlayDuration);
+ mediaVideoItem.addOverlay(overlayFrame[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to add & create Overlay\t" + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ assertEquals("Removing Overlays", overlayFrame[i],
+ mediaVideoItem.removeOverlay((overlayFrame[i].getId())));
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to remove Overlay\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceOverlayVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of get properties of a Video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_007
+ @LargeTest
+ public void testPerformanceVideoItemProperties() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10100;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int fileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int duration = 77366;
+ final int videoBitrate = 3169971;
+ final int fps = 30;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int width = 1080;
+ final int height = MediaProperties.HEIGHT_720;
+ float timeTaken = 0.0f;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m0", videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS*10); i++) {
+ try {
+ assertEquals("Aspect Ratio Mismatch",
+ aspectRatio, mediaVideoItem.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ fileType, mediaVideoItem.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaVideoItem.getVideoType());
+ assertEquals("duration Mismatch",
+ duration, mediaVideoItem.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaVideoItem.getVideoProfile());
+ assertEquals("Video height ",
+ height, mediaVideoItem.getHeight());
+ assertEquals("Video width ",
+ width, mediaVideoItem.getWidth());
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS*10));
+ loggingInfo[0] = "Time taken to get Media Properties\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceVideoItemProperties:", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_008
+ @LargeTest
+ public void testPerformanceGeneratePreviewWithTransitions()
+ throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem, mediaImageItem,
+ 5000, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += (duration2 - duration1);
+ }
+ final long durationToAddObjects = averageTime;
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate Preview with transition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceGeneratePreviewWithTransitions:",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with KenBurn
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_009
+ @LargeTest
+ public void testPerformanceWithKenBurn() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
+ (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
+ (mediaImageItem.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
+ mediaImageItem.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem =
+ new EffectKenBurns(mediaImageItem, "KBOnM2", startRect, endRect,
+ 500, 3000);
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mediaImageItem.removeEffect(kbEffectOnMediaItem.getId());
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+ averageTime += duration2 - duration1;
+ }
+
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate KenBurn Effect \t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceWithKenBurn", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions and
+ * Effect,Overlapping scenario
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_010
+ @LargeTest
+ public void testPerformanceEffectOverlappingTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoStartTime1 = 0;
+ final int videoEndTime1 = 10000;
+ final int videoStartTime2 = 0;
+ final int videoEndTime2 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime = 5000;
+ final int effectItemDurationTime = 5000;
+ final int effectType = EffectColor.TYPE_COLOR;
+ final int effectColorType = EffectColor.GREEN;
+ long averageDuration = 0;
+
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mediaVideoItem1.setExtractBoundaries(videoStartTime1, videoEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mediaVideoItem2.setExtractBoundaries(videoStartTime2, videoEndTime2);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor = new EffectColor(mediaVideoItem1,
+ "effect", effectItemStartTime, effectItemDurationTime, effectType,
+ effectColorType);
+ mediaVideoItem1.addEffect(effectColor);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageDuration += (duration2 - duration1);
+ }
+ SystemClock.uptimeMillis();
+ final long durationToAddObjects = (averageDuration);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] =
+ "Time taken to testPerformanceEffectOverlappingTransition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceEffectOverlappingTransition:",
+ loggingInfo);
+ }
+
+ /**
+ * To test creation of story board with Transition and Two Effects, Effect
+ * overlapping transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_011
+ @LargeTest
+ public void testPerformanceTransitionWithEffectOverlapping() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime1 = 5000;
+ final int effectItemDurationTime1 = 5000;
+ final int effectType1 = EffectColor.TYPE_COLOR;
+ final int effectColorType1 = EffectColor.GREEN;
+ final int effectItemStartTime2 = 5000;
+ final int effectItemDurationTime2 = 5000;
+ final int effectType2 = EffectColor.TYPE_COLOR;
+ final int effectColorType2 = EffectColor.GREEN;
+ int averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor1 = new EffectColor(mediaVideoItem1,
+ "effect1", effectItemStartTime1, effectItemDurationTime1,
+ effectType1, effectColorType1);
+ mediaVideoItem1.addEffect(effectColor1);
+
+ final EffectColor effectColor2 = new EffectColor(mediaVideoItem2,
+ "effect2", effectItemStartTime2, effectItemDurationTime2,
+ effectType2, effectColorType2);
+ mediaVideoItem2.addEffect(effectColor2);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += duration2 - duration1;
+ }
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceTransitionWithEffectOverlapping",
+ loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_12
+ @LargeTest
+ public void testThumbnailH264NonIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 2400;
+ long durationToAddObjects = 0;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken for Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264NonIFrame", loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_13
+ @LargeTest
+ public void testThumbnailH264AnIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 3000;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ long durationToAddObjects = 0;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264AnIFrame", loggingInfo);
+ }
+
+ /**
+ * To test the performance : With an audio track
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_014
+ @LargeTest
+ public void testPerformanceWithAudioTrack() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[2];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ long beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken for 1st Audio Track (AACLC)\t"
+ + timeTaken;
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB)\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceWithAudioTrack", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the
+ * image media item with 640 x 480
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_015
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem640x480() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+
+ float timeTaken = 0.0f;
+
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item (640x480)\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceAddRemoveImageItem640x480 (in mSec)", loggingInfo);
+ }
+
+
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index b694d16..b2086d6 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -65,23 +65,23 @@
output.write("File Name: " + filename);
output.write(" Complete: " + CodecTest.onCompleteSuccess);
output.write(" Error: " + CodecTest.mPlaybackError);
- output.write(" Unknown Info: " + CodecTest.mIsMediaInfoUnknown);
- output.write(" Track Lagging: " + CodecTest.mIsMediaInfoVideoTrackLagging);
- output.write(" BadInterleaving: " + CodecTest.mIsMediaInfoBadInterleaving);
- output.write(" Not Seekable: " + CodecTest.mIsMediaInfoNotSeekable);
- output.write(" Info Meta data update: " + CodecTest.mIsMediaInfoMetdataUpdate);
+ output.write(" Unknown Info: " + CodecTest.mMediaInfoUnknownCount);
+ output.write(" Track Lagging: " + CodecTest.mMediaInfoVideoTrackLaggingCount);
+ output.write(" Bad Interleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
+ output.write(" Not Seekable: " + CodecTest.mMediaInfoNotSeekableCount);
+ output.write(" Info Meta data update: " + CodecTest.mMediaInfoMetdataUpdateCount);
output.write("\n");
}
private void writeTestSummary(Writer output) throws Exception{
output.write("Total Result:\n");
- output.write(" Complete: " + mTotalComplete);
- output.write(" Error: " + mTotalPlaybackError);
- output.write(" Unknown Info: " + mTotalInfoUnknown);
- output.write(" Track Lagging: " + mTotalVideoTrackLagging );
- output.write(" BadInterleaving: " + mTotalBadInterleaving);
- output.write(" Not Seekable: " + mTotalNotSeekable);
- output.write(" Info Meta data update: " + mTotalMetaDataUpdate);
+ output.write("Total Complete: " + mTotalComplete + "\n");
+ output.write("Total Error: " + mTotalPlaybackError + "\n");
+ output.write("Total Unknown Info: " + mTotalInfoUnknown + "\n");
+ output.write("Total Track Lagging: " + mTotalVideoTrackLagging + "\n" );
+ output.write("Total Bad Interleaving: " + mTotalBadInterleaving + "\n");
+ output.write("Total Not Seekable: " + mTotalNotSeekable + "\n");
+ output.write("Total Info Meta data update: " + mTotalMetaDataUpdate + "\n");
output.write("\n");
}
@@ -92,21 +92,11 @@
else if (CodecTest.mPlaybackError){
mTotalPlaybackError++;
}
- else if (CodecTest.mIsMediaInfoUnknown){
- mTotalInfoUnknown++;
- }
- else if (CodecTest.mIsMediaInfoVideoTrackLagging){
- mTotalVideoTrackLagging++;
- }
- else if (CodecTest.mIsMediaInfoBadInterleaving){
- mTotalBadInterleaving++;
- }
- else if (CodecTest.mIsMediaInfoNotSeekable){
- mTotalNotSeekable++;
- }
- else if (CodecTest.mIsMediaInfoMetdataUpdate){
- mTotalMetaDataUpdate++;
- }
+ mTotalInfoUnknown += CodecTest.mMediaInfoUnknownCount;
+ mTotalVideoTrackLagging += CodecTest.mMediaInfoVideoTrackLaggingCount;
+ mTotalBadInterleaving += CodecTest.mMediaInfoBadInterleavingCount;
+ mTotalNotSeekable += CodecTest.mMediaInfoNotSeekableCount;
+ mTotalMetaDataUpdate += CodecTest.mMediaInfoMetdataUpdateCount;
}
//Test that will start the playback for all the videos
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
new file mode 100755
index 0000000..0e70dd3
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
@@ -0,0 +1,1317 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.stress;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.List;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+import android.media.videoeditor.VideoEditorFactory;
+import android.media.videoeditor.ExtractAudioWaveformProgressListener;
+
+import android.os.Debug;
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorStressTest
+ extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorStressMemOutput.txt";
+
+ private long BeginJavaMemory;
+ private long AfterJavaMemory;
+
+ private long BeginNativeMemory;
+ private long AfterNativeMemory;
+
+ public VideoEditorStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ new File(VIDEOEDITOR_OUTPUT).delete();
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.close();
+ }
+
+ private void writeTestCaseHeader(String testCaseName)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write("\n\n" + testCaseName + "\n");
+ output.close();
+ }
+
+ private void getBeginMemory() throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ BeginNativeMemory = Debug.getNativeHeapAllocatedSize();
+ }
+ private void getAfterMemory_updateLog(String[] loggingInfo, boolean when,
+ int iteration)
+ throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ AfterNativeMemory = Debug.getNativeHeapAllocatedSize();
+ if(when == false){
+ loggingInfo[0] = "\n Before Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ } else {
+ loggingInfo[0] = "\n After Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ }
+ writeTimingInfo(loggingInfo);
+ }
+
+ /**
+ * To stress test MediaItem(Video Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_001
+ @LargeTest
+ public void testStressAddRemoveVideoItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_176x144_15fps_144kbps_AMRNB_8kHz_12.2kbps_m_1_17.3gp";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
+ final String videoItemFileName4 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressAddRemoveVideoItem");
+ int i = 0;
+ getBeginMemory();
+
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 5000);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2" + i, videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(30000, 45000);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem4 = new MediaVideoItem(mVideoEditor,
+ "m4" + i, videoItemFileName4, renderingMode);
+ mediaItem4.setExtractBoundaries(10000, 30000);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test MediaItem(Image Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_002
+ @LargeTest
+ public void testStressAddRemoveImageItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String ImageItemFileName1 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName3 = INPUT_FILE_PATH +
+ "IMG_320x240.jpg";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaImageItem mediaItem1 = new MediaImageItem(mVideoEditor,
+ "m1"+ i, ImageItemFileName1, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2"+ i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem3 = new MediaImageItem(mVideoEditor,
+ "m3"+ i, ImageItemFileName3, 15000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4"+ i, ImageItemFileName4, 20000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1"+i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2"+i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3"+i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_003
+ @LargeTest
+ public void testStressAddRemoveTransition() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveTransition");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, null,
+ mediaItem1, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" +i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ mediaItem3.setExtractBoundaries(0, 10000);
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem2,
+ mediaItem3, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+
+ mediaItem3.setExtractBoundaries(0, 6000);
+
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transSlide" +i, mediaItem2,
+ mediaItem3, 3000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
+ mVideoEditor.addTransition(transition2And3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(0, 5000);
+
+ final TransitionFadeBlack transition3 =
+ mVideoEditorHelper.createTFadeBlack("transFB" +i, mediaItem3,
+ null, 2500, Transition.BEHAVIOR_SPEED_UP);
+ transition3.setDuration(500);
+ mVideoEditor.addTransition(transition3);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeTransition("transCF" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeTransition("transAlpha" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeTransition("transSlide" +i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test overlay
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_004
+ @LargeTest
+ public void testStressAddRemoveOverlay() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String OverlayFile4 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay2.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveOverlay");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile3, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 1) {
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem2, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem2.addOverlay(overlayFrame);
+ mediaItem2.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 2) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 0, mediaItem1.getDuration());
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test Effects
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_005
+ @LargeTest
+ public void testStressAddRemoveEffects() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ int i = 0;
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveEffects");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ 10000, (mediaItem1.getTimelineDuration()-1000),
+ EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 1) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 0, 4000, EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getTimelineDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 3) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 10000, 4000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 4) {
+ mediaItem2.setDuration(20000);
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration() - 500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 1) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 3) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 4) {
+ mediaItem1.removeEffect("KBOnM2"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Video
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_006
+ @LargeTest
+ public void testStressThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ writeTestCaseHeader("testStressThumbnailVideoItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*3,
+ mediaVideoItem.getHeight()*2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()/2,
+ mediaVideoItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*2,
+ mediaVideoItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth(),
+ mediaVideoItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test media properties
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_007
+ @LargeTest
+ public void testStressMediaProperties() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String AudioItemFileName3 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final int videoAspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int videoFileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int videoDuration = 77366;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int videoHeight = MediaProperties.HEIGHT_720;
+ final int videoWidth = 1080;
+
+ final int imageAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ final int imageFileType = MediaProperties.FILE_JPEG;
+ final int imageWidth = 640;
+ final int imageHeight = MediaProperties.HEIGHT_480;
+
+ final int audioDuration = 77554;
+ final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
+ final int audioSamplingFrequency = 44100;
+ final int audioChannel = 2;
+ writeTestCaseHeader("testStressMediaProperties");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ assertEquals("Aspect Ratio Mismatch",
+ videoAspectRatio, mediaItem1.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ videoFileType, mediaItem1.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaItem1.getVideoType());
+ assertEquals("duration Mismatch",
+ videoDuration, mediaItem1.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaItem1.getVideoProfile());
+ assertEquals("Video height ",
+ videoHeight, mediaItem1.getHeight());
+ assertEquals("Video width ",
+ videoWidth, mediaItem1.getWidth());
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 3 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ assertEquals("Aspect Ratio Mismatch",
+ imageAspectRatio, mediaItem2.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ imageFileType, mediaItem2.getFileType());
+ assertEquals("Image height",
+ imageHeight, mediaItem2.getHeight());
+ assertEquals("Image width",
+ imageWidth, mediaItem2.getWidth());
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 3 == 2) {
+ final AudioTrack mediaItem3 = new AudioTrack(mVideoEditor,
+ "m3" + i, AudioItemFileName3);
+ mVideoEditor.addAudioTrack(mediaItem3);
+ assertEquals("AudioType Mismatch", audioCodecType,
+ mediaItem3.getAudioType());
+ assertEquals("Audio Sampling", audioSamplingFrequency,
+ mediaItem3.getAudioSamplingFrequency());
+ assertEquals("Audio Channels",
+ audioChannel, mediaItem3.getAudioChannels());
+ assertEquals("duration Mismatch", audioDuration,
+ mediaItem3.getDuration());
+ mVideoEditor.removeAudioTrack("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test insert and move of mediaitems
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_008
+ @LargeTest
+ public void testStressInsertMovieItems() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressInsertMoveItems");
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 15000);
+ mVideoEditor.insertMediaItem(mediaItem3, "m1");
+ mVideoEditor.moveMediaItem("m2", "m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : load and save
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_009
+ @LargeTest
+ public void testStressLoadAndSave() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String OverlayFile6 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final String[] projectPath = new String[10];
+ writeTestCaseHeader("testStressLoadAndSave");
+ getBeginMemory();
+ for( i=0; i < 10; i++){
+
+ projectPath[i] =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ final VideoEditor mVideoEditor1 =
+ mVideoEditorHelper.createVideoEditor(projectPath[i]);
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor1,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor1,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor1,
+ "m3", VideoItemFileName3, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor1,
+ "m4", ImageItemFileName4, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor1,
+ "m5", ImageItemFileName5, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem5);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem3, "effect1",
+ 10000, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem3.addEffect(effectColor1);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile6,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem4, "overlay",
+ mBitmap, 4000, 1000);
+ mediaItem4.addOverlay(overlayFrame);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor1.addTransition(tranCrossfade);
+
+ final EffectColor effectColor2 =
+ mVideoEditorHelper.createEffectItem(mediaItem4, "effect2", 0,
+ mediaItem4.getDuration(), EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem4.addEffect(effectColor2);
+
+ mVideoEditor1.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor1.save();
+ mVideoEditor1.release();
+
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for( i=0; i<10; i++){
+ final VideoEditor mVideoEditor1b =
+ VideoEditorFactory.load(projectPath[i], true);
+ List<MediaItem> mediaList = mVideoEditor1b.getAllMediaItems();
+ assertEquals("Media Item List Size", 5, mediaList.size());
+
+ mediaList.get(3).removeEffect("effect1");
+ mediaList.get(3).removeEffect("effect2");
+ mediaList.get(2).removeOverlay("overlay");
+ mVideoEditor1b.removeTransition("transCF");
+ mVideoEditor1b.removeMediaItem("m5");
+ mVideoEditor1b.removeMediaItem("m4");
+ mVideoEditor1b.removeMediaItem("m3");
+ mVideoEditor1b.removeMediaItem("m2");
+ mVideoEditor1b.removeMediaItem("m1");
+ mVideoEditor1b.release();
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : Multiple Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_010
+ @LargeTest
+ public void testStressMultipleExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper.createRandomFile(
+ mVideoEditor.getPath() + "/") + ".3gp";
+ int i = 0;
+ writeTestCaseHeader("testStressMultipleExport");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ for ( i = 0; i < 50; i++) {
+ if(i%4 ==0){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_256K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H263,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==1){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_384K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_MPEG4,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==2){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_512K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==3){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_800K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test Media Item,Overlays,Transitions and Ken Burn
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_011
+ @LargeTest
+ public void testStressOverlayTransKenBurn() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_640x480_30fps_256kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String audioFilename4 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ int i = 0;
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressOverlayTransKenBurn");
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, mediaItem1,
+ mediaItem2, 4000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile3,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration()-500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+
+ if(i == 5) {
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename4);
+ mVideoEditor.addAudioTrack(audioTrack1);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ MediaImageItem m2 = (MediaImageItem)mVideoEditor.getMediaItem("m2"+i);
+ MediaVideoItem m1 = (MediaVideoItem)mVideoEditor.getMediaItem("m1"+i);
+ m2.removeEffect("KBOnM2" + i);
+ m1.removeOverlay("overlay" + i);
+ mVideoEditor.removeTransition("transCF" + i);
+ m1.removeEffect("effect1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ if(i == 5) {
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track with Video
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_012
+ @LargeTest
+ public void testStressAudioTrackVideo() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+ writeTestCaseHeader("testStressAudioTrackVideo");
+ getBeginMemory();
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("mediaItem1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To Test Stress : Story Board creation with out preview or export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_013
+ @LargeTest
+ public void testStressStoryBoard() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
+ final String videoItemFileName3= INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String imageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String imageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String audioFilename6 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String audioFilename7 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+
+ writeTestCaseHeader("testStressStoryBoard");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName4, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor,
+ "m5", imageItemFileName5, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem5);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem2, mediaItem3, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final TransitionCrossfade tranCrossfade1 =
+ new TransitionCrossfade("transCF1", mediaItem3, mediaItem4, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade1);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename6);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename7);
+ mVideoEditor.addAudioTrack(audioTrack2);
+ audioTrack2.enableLoop();
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeAudioTrack("Audio Track2");
+ mVideoEditor.removeTransition("transCF");
+ mVideoEditor.removeTransition("transCF1");
+ mVideoEditor.removeMediaItem("m5");
+ mVideoEditor.removeMediaItem("m4");
+ mVideoEditor.removeMediaItem("m3");
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track Only
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_014
+ @LargeTest
+ public void testStressAudioTrackOnly() throws Exception {
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String AudioItemFileName1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAudioTrackOnly");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final AudioTrack mediaItem1 = new AudioTrack(mVideoEditor,
+ "m1" + i, AudioItemFileName1);
+ mVideoEditor.addAudioTrack(mediaItem1);
+ mediaItem1.enableLoop();
+ mVideoEditor.removeAudioTrack("m1" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Image
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_016 -- New Test Case
+ @LargeTest
+ public void testStressThumbnailImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "m1", imageItemFileName, 5000, renderingMode);
+ writeTestCaseHeader("testStressThumbnailImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2 ,
+ mediaImageItem.getHeight() / 2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2,
+ mediaImageItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() * 2,
+ mediaImageItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth(),
+ mediaImageItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+}
diff --git a/native/android/input.cpp b/native/android/input.cpp
index a96240c..ed26667 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -172,6 +172,11 @@
return static_cast<const MotionEvent*>(motion_event)->getOrientation(pointer_index);
}
+float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
+ int32_t axis, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getAxisValue(axis, pointer_index);
+}
+
size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event) {
return static_cast<const MotionEvent*>(motion_event)->getHistorySize();
}
@@ -248,6 +253,12 @@
pointer_index, history_index);
}
+float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
+ int32_t axis, size_t pointer_index, size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalAxisValue(
+ axis, pointer_index, history_index);
+}
+
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
int ident, ALooper_callbackFunc callback, void* data) {
diff --git a/native/include/android/input.h b/native/include/android/input.h
index bad363d..d516037 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -281,7 +281,13 @@
/* A non-primary pointer has gone up.
* The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
*/
- AMOTION_EVENT_ACTION_POINTER_UP = 6
+ AMOTION_EVENT_ACTION_POINTER_UP = 6,
+
+ /* A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
+ * The motion contains the most recent point, as well as any intermediate points since
+ * the last hover move event.
+ */
+ AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
};
/*
@@ -321,6 +327,51 @@
};
/*
+ * Constants that identify each individual axis of a motion event.
+ * Refer to the documentation on the MotionEvent class for descriptions of each axis.
+ */
+enum {
+ AMOTION_EVENT_AXIS_X = 0,
+ AMOTION_EVENT_AXIS_Y = 1,
+ AMOTION_EVENT_AXIS_PRESSURE = 2,
+ AMOTION_EVENT_AXIS_SIZE = 3,
+ AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,
+ AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,
+ AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,
+ AMOTION_EVENT_AXIS_TOOL_MINOR = 7,
+ AMOTION_EVENT_AXIS_ORIENTATION = 8,
+ AMOTION_EVENT_AXIS_VSCROLL = 9,
+ AMOTION_EVENT_AXIS_HSCROLL = 10,
+ AMOTION_EVENT_AXIS_Z = 11,
+ AMOTION_EVENT_AXIS_RX = 12,
+ AMOTION_EVENT_AXIS_RY = 13,
+ AMOTION_EVENT_AXIS_RZ = 14,
+ AMOTION_EVENT_AXIS_HAT_X = 15,
+ AMOTION_EVENT_AXIS_HAT_Y = 16,
+ AMOTION_EVENT_AXIS_LTRIGGER = 17,
+ AMOTION_EVENT_AXIS_RTRIGGER = 18,
+ AMOTION_EVENT_AXIS_GENERIC_1 = 32,
+ AMOTION_EVENT_AXIS_GENERIC_2 = 33,
+ AMOTION_EVENT_AXIS_GENERIC_3 = 34,
+ AMOTION_EVENT_AXIS_GENERIC_4 = 35,
+ AMOTION_EVENT_AXIS_GENERIC_5 = 36,
+ AMOTION_EVENT_AXIS_GENERIC_6 = 37,
+ AMOTION_EVENT_AXIS_GENERIC_7 = 38,
+ AMOTION_EVENT_AXIS_GENERIC_8 = 39,
+ AMOTION_EVENT_AXIS_GENERIC_9 = 40,
+ AMOTION_EVENT_AXIS_GENERIC_10 = 41,
+ AMOTION_EVENT_AXIS_GENERIC_11 = 42,
+ AMOTION_EVENT_AXIS_GENERIC_12 = 43,
+ AMOTION_EVENT_AXIS_GENERIC_13 = 44,
+ AMOTION_EVENT_AXIS_GENERIC_14 = 45,
+ AMOTION_EVENT_AXIS_GENERIC_15 = 46,
+ AMOTION_EVENT_AXIS_GENERIC_16 = 47,
+
+ // NOTE: If you add a new axis here you must also add it to several other files.
+ // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+};
+
+/*
* Input sources.
*
* Refer to the documentation on android.view.InputDevice for more details about input sources
@@ -368,18 +419,20 @@
*
* Refer to the documentation on android.view.InputDevice for more details about input sources
* and their correct interpretation.
+ *
+ * DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
*/
enum {
- AINPUT_MOTION_RANGE_X = 0,
- AINPUT_MOTION_RANGE_Y = 1,
- AINPUT_MOTION_RANGE_PRESSURE = 2,
- AINPUT_MOTION_RANGE_SIZE = 3,
- AINPUT_MOTION_RANGE_TOUCH_MAJOR = 4,
- AINPUT_MOTION_RANGE_TOUCH_MINOR = 5,
- AINPUT_MOTION_RANGE_TOOL_MAJOR = 6,
- AINPUT_MOTION_RANGE_TOOL_MINOR = 7,
- AINPUT_MOTION_RANGE_ORIENTATION = 8,
-};
+ AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
+ AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
+ AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
+ AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
+ AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
+ AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
+ AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
+ AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
+ AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,
+} __attribute__ ((deprecated));
/*
@@ -526,7 +579,7 @@
/* Get the current pressure of this event for the given pointer index.
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
+ * although values higher than 1 may be generated depending on the calibration of
* the input device. */
float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
@@ -568,6 +621,10 @@
* (finger pointing fully right). */
float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
+/* Get the value of the request axis for the given pointer index. */
+float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
+ int32_t axis, size_t pointer_index);
+
/* Get the number of historical points in this event. These are movements that
* have occurred between this event and the previous event. This only applies
* to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
@@ -614,7 +671,7 @@
/* Get the historical pressure of this event for the given pointer index that
* occurred between this event and the previous motion event.
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
+ * although values higher than 1 may be generated depending on the calibration of
* the input device. */
float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
size_t history_index);
@@ -669,6 +726,11 @@
float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
size_t history_index);
+/* Get the historical value of the request axis for the given pointer index
+ * that occurred between this event and the previous motion event. */
+float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
+ int32_t axis, size_t pointer_index, size_t history_index);
+
/*
* Input queue
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3dc8c03f..3d5a4d1 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -22,7 +22,7 @@
#include <sys/ioctl.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f8809d7..9017ca3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -17,11 +17,7 @@
package com.android.providers.settings;
import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
-import java.util.LinkedHashMap;
-import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -47,6 +43,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.LruCache;
public class SettingsProvider extends ContentProvider {
private static final String TAG = "SettingsProvider";
@@ -293,7 +290,7 @@
"" + (MAX_CACHE_ENTRIES + 1) /* limit */);
try {
synchronized (cache) {
- cache.clear();
+ cache.evictAll();
cache.setFullyMatchesDisk(true); // optimistic
int rows = 0;
while (c.moveToNext()) {
@@ -359,8 +356,8 @@
// possibly with a null value, or null on failure.
private Bundle lookupValue(String table, SettingsCache cache, String key) {
synchronized (cache) {
- if (cache.containsKey(key)) {
- Bundle value = cache.get(key);
+ Bundle value = cache.get(key);
+ if (value != null) {
if (value != TOO_LARGE_TO_CACHE_MARKER) {
return value;
}
@@ -725,13 +722,13 @@
* associated helper functions to keep cache coherent with the
* database.
*/
- private static final class SettingsCache extends LinkedHashMap<String, Bundle> {
+ private static final class SettingsCache extends LruCache<String, Bundle> {
private final String mCacheName;
private boolean mCacheFullyMatchesDisk = false; // has the whole database slurped.
public SettingsCache(String name) {
- super(MAX_CACHE_ENTRIES, 0.75f /* load factor */, true /* access ordered */);
+ super(MAX_CACHE_ENTRIES);
mCacheName = name;
}
@@ -751,14 +748,8 @@
}
@Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- if (size() <= MAX_CACHE_ENTRIES) {
- return false;
- }
- synchronized (this) {
- mCacheFullyMatchesDisk = false;
- }
- return true;
+ protected synchronized void entryEvicted(String key, Bundle value) {
+ mCacheFullyMatchesDisk = false;
}
/**
@@ -772,7 +763,7 @@
Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {
synchronized (this) {
- if (!containsKey(key)) {
+ if (get(key) == null) {
put(key, bundle);
}
}
@@ -826,7 +817,7 @@
return;
}
synchronized (cache) {
- cache.clear();
+ cache.evictAll();
cache.mCacheFullyMatchesDisk = false;
}
}
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
new file mode 100644
index 0000000..6d4da7f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
index c358e13..d7e1633 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
@@ -58,26 +58,33 @@
/>
<TextView android:id="@+id/app_label"
- android:layout_width="113dip"
+ android:layout_width="97dip"
android:layout_height="wrap_content"
android:textSize="18dip"
- android:fadingEdge="none"
- android:fadingEdgeLength="0dp"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="10dip"
android:scrollHorizontally="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dip"
android:layout_marginTop="32dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
/>
<TextView android:id="@+id/app_description"
- android:layout_width="wrap_content"
+ android:layout_width="97dip"
android:layout_height="wrap_content"
android:textSize="18dip"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="10dip"
+ android:scrollHorizontally="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dip"
android:layout_marginTop="61dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/res/values-ar-xlarge/strings.xml b/packages/SystemUI/res/values-ar-xlarge/strings.xml
index be4334f..d689df6 100644
--- a/packages/SystemUI/res/values-ar-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ar-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"محو الكل"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"لا اتصال بالإنترنت"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5f01f4d..486dacc 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"التنبيهات"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"حديثة"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"ليس هناك أية تطبيقات حديثة."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"التطبيقات"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"تم إنشاء الاتصال بالإنترنت عن طريق البلوتوث."</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"تهيئة طرق الإدخال"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"استخدام لوحة المفاتيح الفعلية"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg-xlarge/strings.xml b/packages/SystemUI/res/values-bg-xlarge/strings.xml
index 8dd6d7c..ec632ec 100644
--- a/packages/SystemUI/res/values-bg-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-bg-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Изчистване на всичко"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Изчистване"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Няма връзка с интернет"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: има връзка"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index aa98f7d..df6ef71 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Известия"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Скорошни"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Няма скорошни приложения."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Приложения"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth има връзка с тетъринг"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриране на въвеждането"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Използване на физ. клав."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca-xlarge/strings.xml b/packages/SystemUI/res/values-ca-xlarge/strings.xml
index 289a2a3..950d845 100644
--- a/packages/SystemUI/res/values-ca-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ca-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Esborra-ho tot"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Esborra-ho"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connexió Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connectat"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 583044d..2993e8b 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificacions"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recents"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"No hi ha aplicacions recents."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth sense fil"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura mètodes d\'entrada"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilitza un teclat físic"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs-land/strings.xml b/packages/SystemUI/res/values-cs-land/strings.xml
new file mode 100644
index 0000000..58e08cb
--- /dev/null
+++ b/packages/SystemUI/res/values-cs-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Obrazovka je nyní uzamčena v orientaci na šířku."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-cs-xlarge/strings.xml b/packages/SystemUI/res/values-cs-xlarge/strings.xml
index b257792..c3cdd9a 100644
--- a/packages/SystemUI/res/values-cs-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-cs-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazat vše"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Žádné připojení"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: připojeno"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ea5694d..29ab1a7 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Žádné nedávno použité aplikace."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikace"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nakonfigurovat metody vstupu"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použít fyz. klávesnici"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da-land/strings.xml b/packages/SystemUI/res/values-da-land/strings.xml
new file mode 100644
index 0000000..7ad3faba
--- /dev/null
+++ b/packages/SystemUI/res/values-da-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Skærmen er nu låst i liggende retning."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-da-xlarge/strings.xml b/packages/SystemUI/res/values-da-xlarge/strings.xml
index 78107ab..7712a41 100644
--- a/packages/SystemUI/res/values-da-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-da-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ryd alt"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen internetforb."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi er forbundet"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b95c6cb..81122a8 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Meddelelser"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Der er ingen nye programmer."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programmer"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inputmetoder"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de-land/strings.xml b/packages/SystemUI/res/values-de-land/strings.xml
new file mode 100644
index 0000000..c9336cb
--- /dev/null
+++ b/packages/SystemUI/res/values-de-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Bildschirm bleibt jetzt im Querformat."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-de-xlarge/strings.xml b/packages/SystemUI/res/values-de-xlarge/strings.xml
index 73c563c..bc5dca2 100644
--- a/packages/SystemUI/res/values-de-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-de-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Alle löschen"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Keine Internetverbindung"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Mit WLAN verbunden"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4043c2e..1ea87e8 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Benachrichtigungen"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Zuletzt verwendet"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Keine neuen Anwendungen"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-Tethering aktiv"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Eingabemethoden konfigurieren"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Physische Tastatur"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el-land/strings.xml b/packages/SystemUI/res/values-el-land/strings.xml
new file mode 100644
index 0000000..a513c74
--- /dev/null
+++ b/packages/SystemUI/res/values-el-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Ο προσανατολισμός της οθόνης κλειδώθηκε σε οριζόντια προβολή."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-el-xlarge/strings.xml b/packages/SystemUI/res/values-el-xlarge/strings.xml
index 41f61e2..ab72f4a 100644
--- a/packages/SystemUI/res/values-el-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-el-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Διαγ. όλων"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Χωρίς σύνδ. σε Διαδ."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: συνδέθηκε"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 39a462c..cd412f4 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Ειδοποιήσεις"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Δεν υπάρχουν πρόσφατες εφαρμογές."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Διαμόρφωση μεθόδων εισαγωγής"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Χρήση κανονικού πληκτρολ."</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml b/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
index fac0137..f31c829 100644
--- a/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Clear all"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No Internet connection"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi connected"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 72373bb..2bd662b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"No recent applications."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configure input methods"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Use physical keyboard"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-land/strings.xml b/packages/SystemUI/res/values-es-land/strings.xml
new file mode 100644
index 0000000..dad10b3
--- /dev/null
+++ b/packages/SystemUI/res/values-es-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"La pantalla está ahora bloqueada en orientación horizontal."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-land/strings.xml b/packages/SystemUI/res/values-es-rUS-land/strings.xml
new file mode 100644
index 0000000..558c648
--- /dev/null
+++ b/packages/SystemUI/res/values-es-rUS-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"La pantalla está bloqueada en orientación paisaje."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
index 22c8002..15a602f 100644
--- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
@@ -1,22 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- XL xlarge -->
- <string name="status_bar_clear_all_button" msgid="4341545325987974494">"Eliminar todos"</string>
- <!-- XL -->
- <string name="status_bar_no_notifications_title" msgid="2492933749414725897">"No tienes notificaciones"</string>
- <!-- XL -->
- <string name="status_bar_settings_rotation_lock" msgid="9125161825884157545">"Bloquear orient. de pant."</string>
- <!-- XL -->
- <string name="recent_tasks_app_label" msgid="5550538721034982973">"Google Apps"</string>
- <!-- XL xlarge -->
- <string name="status_bar_settings_signal_meter_disconnected" msgid="4866302415753953027">"Sin conexión a Internet"</string>
- <!-- XL xlarge -->
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="3832182580451976589">"Wi-Fi conectado"</string>
-
- <!-- manually translated -->
- <string name="gps_notification_searching_text">Buscando señal de GPS</string>
-
- <!-- manually translated -->
- <string name="gps_notification_found_text">Ubicación establecida por el GPS</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Eliminar todos"</string>
+ <string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Int."</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"WiFi conectado"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c38abdd..2c50160 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
- <!-- outdated translation 5550538721034982973 --> <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
- <!-- outdated translation 8017158699581472359 --> <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
- <!-- outdated translation 3875357213648023768 --> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
- <string name="status_bar_use_physical_keyboard">"Usar un teclado externo"</string>
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaciones"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar teclado físico"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-xlarge/strings.xml b/packages/SystemUI/res/values-es-xlarge/strings.xml
index 935fdbc..e0451ba 100644
--- a/packages/SystemUI/res/values-es-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Borrar todo"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sin conexión a Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Con conexión WiFi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3acfb45..8d9cc5c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaciones"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de introducción"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa-xlarge/strings.xml b/packages/SystemUI/res/values-fa-xlarge/strings.xml
index 47312a5..5c5f62f 100644
--- a/packages/SystemUI/res/values-fa-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fa-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"پاک کردن همه"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"اتصال اینترنت موجود نیست"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi متصل شد"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0528d68..1e0f1e9 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"اعلان ها"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"اخیر"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"برنامه اخیری موجود نیست."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"برنامه های کاربردی"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"اتصال اینترنتی با بلوتوث تلفن همراه"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"پیکربندی روش های ورودی"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"از صفحه کلید فیزیکی استفاده کنید"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi-xlarge/strings.xml b/packages/SystemUI/res/values-fi-xlarge/strings.xml
index 8b1d91d..9ae24d0 100644
--- a/packages/SystemUI/res/values-fi-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fi-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Poista kaikki"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ei internetyhteyttä"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wifi yhdistetty"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 1ce102a..e2f935a 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Ilmoitukset"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Viimeisimmät"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Ei viimeaikaisia sovelluksia."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Sovellukset"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth yhdistetty"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Määritä syöttötavat"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Käytä fyysistä näppäimistöä"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-land/strings.xml b/packages/SystemUI/res/values-fr-land/strings.xml
new file mode 100644
index 0000000..0cc12ec
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"L\'écran est désormais verrouillé en orientation paysage."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr-xlarge/strings.xml b/packages/SystemUI/res/values-fr-xlarge/strings.xml
index 76e7221..2bee46a 100644
--- a/packages/SystemUI/res/values-fr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-fr-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tout effacer"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Aucune connexion Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Connecté au Wi-Fi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 12308fb..9bd1886 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifications"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Aucune application récente"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Applications"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurer les modes de saisie"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utiliser clavier physique"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr-xlarge/strings.xml b/packages/SystemUI/res/values-hr-xlarge/strings.xml
index cac702a..4830f81 100644
--- a/packages/SystemUI/res/values-hr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-hr-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši sve"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nema int. veze"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: povezano"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 411336a..8034eb7 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Obavijesti"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nedavni"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nema nedavnih aplikacija."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikacije"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth posredno povezan"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguriraj načine ulaza"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Rabi fizičku tipkovnicu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu-xlarge/strings.xml b/packages/SystemUI/res/values-hu-xlarge/strings.xml
index d49266f..6643436 100644
--- a/packages/SystemUI/res/values-hu-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-hu-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Az összes törlése"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Össz.törl."</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nincs internetkapcs."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi csatlakozva"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b82aa77..9a91b13 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Értesítések"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Legutóbbiak"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nincsenek nemrég használt alkalmazások"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Alkalmazások"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth megosztva"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Beviteli módok konfigurálása"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Valódi bill. használata"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in-xlarge/strings.xml b/packages/SystemUI/res/values-in-xlarge/strings.xml
index 81b3d479..8fb9372 100644
--- a/packages/SystemUI/res/values-in-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-in-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Hapus semua"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Tidak ada sambungan internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi tersambung"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index db170ab..8d3cfb1 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pemberitahuan"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Terbaru"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Tidak ada aplikasi terbaru."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tertambat"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurasikan metode masukan"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gunakan keyboard fisik"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it-land/strings.xml b/packages/SystemUI/res/values-it-land/strings.xml
new file mode 100644
index 0000000..d1e9643
--- /dev/null
+++ b/packages/SystemUI/res/values-it-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Lo schermo è bloccato in orientamento orizzontale."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-it-xlarge/strings.xml b/packages/SystemUI/res/values-it-xlarge/strings.xml
index 3b1e302..66718bc 100644
--- a/packages/SystemUI/res/values-it-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-it-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Canc. tutto"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"No connessione Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: connesso"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ca99d86..9e7f53a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notifiche"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nessuna applicazione recente."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Applicazioni"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura metodi di input"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizza tastiera fisica"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw-xlarge/strings.xml b/packages/SystemUI/res/values-iw-xlarge/strings.xml
index 80043b1..5115c7d 100644
--- a/packages/SystemUI/res/values-iw-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-iw-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"נקה הכל"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"אין חיבור לאינטרנט"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi מחובר"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f2d5621..a242d04 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"התראות"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"אחרונות"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"אין יישומים חדשים."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth קשור"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"הגדר שיטות קלט"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"השתמש במקלדת הפיזית"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja-land/strings.xml b/packages/SystemUI/res/values-ja-land/strings.xml
new file mode 100644
index 0000000..292cb2e
--- /dev/null
+++ b/packages/SystemUI/res/values-ja-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"画面を横向きにロックしました。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ja-xlarge/strings.xml b/packages/SystemUI/res/values-ja-xlarge/strings.xml
index a6af041..9aac398 100644
--- a/packages/SystemUI/res/values-ja-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ja-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"すべて消去"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"インターネット未接続"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi接続済み"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 25d8873..869688c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"新着のアプリケーションはありません。"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"アプリ"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetoothテザリング接続"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"入力方法の設定"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"物理キーボードを使用"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko-land/strings.xml b/packages/SystemUI/res/values-ko-land/strings.xml
new file mode 100644
index 0000000..ed5955f
--- /dev/null
+++ b/packages/SystemUI/res/values-ko-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"화면이 현재 가로 방향으로 잠겨 있습니다."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ko-xlarge/strings.xml b/packages/SystemUI/res/values-ko-xlarge/strings.xml
index 4962b5e..21b6845 100644
--- a/packages/SystemUI/res/values-ko-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ko-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"모두 지우기"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"인터넷에 연결되지 않음"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 연결됨"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 6c5970a..32ae7e7 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"알림"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"최근에 사용한 애플리케이션이 없습니다."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"애플리케이션"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"블루투스 테더링됨"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"입력 방법 구성"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"물리적 키보드 사용"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt-xlarge/strings.xml b/packages/SystemUI/res/values-lt-xlarge/strings.xml
index f9b3ac1..ba6f97e 100644
--- a/packages/SystemUI/res/values-lt-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-lt-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Išvalyti viską"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Išv. viską"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nėra interneto ryšio"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Prisijungta prie „Wi-Fi“"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 90a5e44..01cdffd 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Pranešimai"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Naujos"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nėra naujausių programų."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"„Bluetooth“ susieta"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigūruoti įvesties metodus"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Naudoti fizinę klaviatūrą"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv-xlarge/strings.xml b/packages/SystemUI/res/values-lv-xlarge/strings.xml
index af3423f..d5352b9 100644
--- a/packages/SystemUI/res/values-lv-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-lv-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Notīrīt visu"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Notīr.visu"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nav interneta sav."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Izv. sav. ar Wi-Fi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index fb33329..817e1d5 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Paziņojumi"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nesens"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nav nesenu lietojumprogrammu."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Lietotnes"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth piesaiste"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurēt ievades metodes"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Izmantot fizisku tastatūru"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb-land/strings.xml b/packages/SystemUI/res/values-nb-land/strings.xml
new file mode 100644
index 0000000..b7b6b66
--- /dev/null
+++ b/packages/SystemUI/res/values-nb-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Skjermen er nå låst i liggende retning."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-nb-xlarge/strings.xml b/packages/SystemUI/res/values-nb-xlarge/strings.xml
index 726b061..d749062 100644
--- a/packages/SystemUI/res/values-nb-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-nb-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tøm alt"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Int.-tilkobl."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: tilkoblet"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 82405a8..bb96483 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Varslinger"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Ingen nylig brukte programmer."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programmer"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tilknyttet"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inndatametoder"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Bruk fysisk tastatur"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl-land/strings.xml b/packages/SystemUI/res/values-nl-land/strings.xml
new file mode 100644
index 0000000..d762d07
--- /dev/null
+++ b/packages/SystemUI/res/values-nl-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Het scherm is nu vergrendeld in liggende (landschap) stand."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-nl-xlarge/strings.xml b/packages/SystemUI/res/values-nl-xlarge/strings.xml
index b2946ae..c079f22 100644
--- a/packages/SystemUI/res/values-nl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-nl-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wissen"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Geen internetverb."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Verbonden via Wi-Fi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4efdcbb..faf3f32 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Meldingen"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Geen recente toepassingen."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth getetherd"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Invoermethoden configureren"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fysiek toetsenbord gebruiken"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl-land/strings.xml b/packages/SystemUI/res/values-pl-land/strings.xml
new file mode 100644
index 0000000..be23cc4
--- /dev/null
+++ b/packages/SystemUI/res/values-pl-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Ekran jest teraz zablokowany w orientacji poziomej"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pl-xlarge/strings.xml b/packages/SystemUI/res/values-pl-xlarge/strings.xml
index 8642ea4..4280773 100644
--- a/packages/SystemUI/res/values-pl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pl-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Wyczyść wszystko"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brak połączenia internetowego"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: połączono"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 07ef5ef..77ae7e7 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Powiadomienia"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Brak ostatnio używanych aplikacji."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikacje"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth – podłączono"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguruj metody wprowadzania"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Używaj klawiatury fizycznej"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-land/strings.xml b/packages/SystemUI/res/values-pt-land/strings.xml
new file mode 100644
index 0000000..7b04e7e
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"A tela está bloqueada na orientação cenário."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT-land/strings.xml b/packages/SystemUI/res/values-pt-rPT-land/strings.xml
new file mode 100644
index 0000000..1c3016b
--- /dev/null
+++ b/packages/SystemUI/res/values-pt-rPT-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"O ecrã está agora bloqueado na orientação horizontal."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml b/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
index 8ddb2b1..f807ae9 100644
--- a/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem ligação internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi ligado"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index aa14cce..1215415 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhuma aplicação recente."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicações"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ligado"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-xlarge/strings.xml b/packages/SystemUI/res/values-pt-xlarge/strings.xml
index 103b2ad..d47a8db 100644
--- a/packages/SystemUI/res/values-pt-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-pt-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Limpar tudo"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Sem conex. à inter."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectado"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 17be76a..1f4afb7 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificações"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhum aplicativo recente."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicativos"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth vinculado"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar o teclado físico"</string>
</resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index e3fec88..d4d4600 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -57,4 +57,8 @@
<skip />
<!-- no translation found for bluetooth_tethered (7094101612161133267) -->
<skip />
+ <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+ <skip />
+ <!-- no translation found for status_bar_use_physical_keyboard (3695516942412442936) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro-xlarge/strings.xml b/packages/SystemUI/res/values-ro-xlarge/strings.xml
index 07badf4..c308e42 100644
--- a/packages/SystemUI/res/values-ro-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ro-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ştergeţi-le pe toate"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Şterg. tot"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Fără conex. internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi conectat"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2bb3c14..c3bcc97 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificări"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Nu există aplicaţii recente."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplicaţii"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configuraţi metode de intrare"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizaţi tastat. fizică"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru-land/strings.xml b/packages/SystemUI/res/values-ru-land/strings.xml
new file mode 100644
index 0000000..92c39d4
--- /dev/null
+++ b/packages/SystemUI/res/values-ru-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Выбрана только альбомная ориентация экрана."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ru-xlarge/strings.xml b/packages/SystemUI/res/values-ru-xlarge/strings.xml
index 001f95c8..dc4dd68 100644
--- a/packages/SystemUI/res/values-ru-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-ru-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Удалить все"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нет подключения"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: подключено"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi подкл."</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 89b9cc8..e53fbd2 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Уведомления"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Новых приложений нет"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Приложения"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Общий модем доступен через Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Настроить способ ввода"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Использовать физическую клавиатуру"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk-xlarge/strings.xml b/packages/SystemUI/res/values-sk-xlarge/strings.xml
index ab01a3a..7fe27c8 100644
--- a/packages/SystemUI/res/values-sk-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sk-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Vymazať všetky"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Nepripoj. k Intern."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi: pripojené"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9716327..bf316cc 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Upozornenia"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnovšie"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Žiadne nedávno použité aplikácie."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Aplikácie"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Zdieľané dátové pripojenie cez Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurovať metódy vstupu"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použiť fyzickú klávesnicu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl-xlarge/strings.xml b/packages/SystemUI/res/values-sl-xlarge/strings.xml
index ef50a67..8c8fd56 100644
--- a/packages/SystemUI/res/values-sl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sl-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Počisti vse"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Izbriši vse"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Brez inter. povez."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi – povezano"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b05b93c..c0a7f04 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -32,8 +32,7 @@
<string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto."\n"Uporabite priloženi polnilnik."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Uporaba baterije"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
- <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
- <skip />
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način za letalo"</string>
<string name="status_bar_settings_rotation_lock" msgid="8361452930058000609">"Zakleni usmerjenost zaslona"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"TIHO"</string>
@@ -41,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Obvestila"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nedavno"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Ni novih programov."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Programi"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetna povezava prek Bluetootha"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nastavitev načinov vnosa"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Uporabi fizično tipkovn."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr-xlarge/strings.xml b/packages/SystemUI/res/values-sr-xlarge/strings.xml
index f5fcfbc..b127757 100644
--- a/packages/SystemUI/res/values-sr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sr-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Обриши све"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Нема интернет везе"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi је повезан"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ff1d3fb..bd00a9c 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Обавештења"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавно"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Нема недавних апликација"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Google Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Веза преко Bluetooth-а"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриши методе уноса"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Користи физичку тастатуру"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv-land/strings.xml b/packages/SystemUI/res/values-sv-land/strings.xml
new file mode 100644
index 0000000..0d9c319
--- /dev/null
+++ b/packages/SystemUI/res/values-sv-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Bildskärmens riktning är nu låst i liggande format."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sv-xlarge/strings.xml b/packages/SystemUI/res/values-sv-xlarge/strings.xml
index 9379451..0294198 100644
--- a/packages/SystemUI/res/values-sv-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-sv-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Ta bort alla"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Ingen Internetansl."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi-ansluten"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 06b6880..0537c94 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Aviseringar"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Inga nya program."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Appar"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetdelning via Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurera inmatningsmetoder"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Använd fysiska tangenter"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th-land/strings.xml b/packages/SystemUI/res/values-th-land/strings.xml
index 5cc5013..13fc0f5 100644
--- a/packages/SystemUI/res/values-th-land/strings.xml
+++ b/packages/SystemUI/res/values-th-land/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="toast_rotation_locked" msgid="7609673011431556092">"ขณะนี้หน้าจอถูกล็อกการวางแนวในแนวนอน"</string>
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"ขณะนี้หน้าจอถูกล็อกในแนวนอน"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th-xlarge/strings.xml b/packages/SystemUI/res/values-th-xlarge/strings.xml
index fb4cbae..73fc2fc 100644
--- a/packages/SystemUI/res/values-th-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-th-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"ล้างทั้งหมด"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"ล้างหมด"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"ไม่มีการเชื่อมต่ออินเทอร์เน็ต"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"เชื่อมต่อ Wi-Fi แล้ว"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2d337a90..c42e26d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"การแจ้งเตือน"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"เมื่อเร็วๆ นี้"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"ไม่มีแอปพลิเคชันล่าสุด"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"แอปพลิเคชัน"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"บลูทูธที่ปล่อยสัญญาณ"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"กำหนดค่าวิธีการป้อนข้อมูล"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"ใช้แป้นพิมพ์จริง"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl-xlarge/strings.xml b/packages/SystemUI/res/values-tl-xlarge/strings.xml
index 3560c96..90f434e 100644
--- a/packages/SystemUI/res/values-tl-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-tl-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"I-clear ang lahat"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"I-clear lahat"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Wala net connection"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Konektado ang WiFi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e94d3cc..1244945 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Mga Notification"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Kamakailan"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Walang kamakailang mga application."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Apps"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Na-tether ang bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"I-configure paraan ng input"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gamitin ang pisikal na keyboard"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr-land/strings.xml b/packages/SystemUI/res/values-tr-land/strings.xml
new file mode 100644
index 0000000..7ea0714
--- /dev/null
+++ b/packages/SystemUI/res/values-tr-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"Ekran şimdi yatay yönde kilitlendi."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-tr-xlarge/strings.xml b/packages/SystemUI/res/values-tr-xlarge/strings.xml
index f7d20b5e..e15d4d1 100644
--- a/packages/SystemUI/res/values-tr-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-tr-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Tümünü temizle"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"İnternet bağlnts yok"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Kablosuz bağlandı"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4c3f818..e911b42 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Bildirimler"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Hiçbir yeni uygulama yok."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Uygulamalar"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth paylaşımı tamam"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Giriş yöntemlerini yapılandır"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fiziksel klavyeyi kullan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk-xlarge/strings.xml b/packages/SystemUI/res/values-uk-xlarge/strings.xml
index 47242a6..9495bc0 100644
--- a/packages/SystemUI/res/values-uk-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-uk-xlarge/strings.xml
@@ -19,7 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Очистити все"</string>
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"Очист. все"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Інтернет не під\'єдн."</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi під\'єднано"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 85ead1c..963a50f 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Сповіщення"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Останні"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Немає останніх програм."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Програми"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Створено прив\'язку Bluetooth"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Налаштувати методи введення"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Викор. реальну клавіатуру"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi-xlarge/strings.xml b/packages/SystemUI/res/values-vi-xlarge/strings.xml
index cd390b3..76d8a8da 100644
--- a/packages/SystemUI/res/values-vi-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-vi-xlarge/strings.xml
@@ -22,4 +22,8 @@
<string name="status_bar_clear_all_button" msgid="4722520806446512408">"Xóa tất cả"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"Không có kết nối Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Đã kết nối Wi-Fi"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 71df0c3..108febf 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Thông báo"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Gần đây"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"Không có ứng dụng nào gần đây."</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"Ứng dụng"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth được dùng làm điểm truy cập Internet"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Định cấu hình phương pháp nhập liệu"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sử dụng bàn phím vật lý"</string>
</resources>
diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml
index dfd5851..35be532 100644
--- a/packages/SystemUI/res/values-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-xlarge/strings.xml
@@ -43,4 +43,11 @@
<!-- Notification text: when GPS has found a fix [CHAR LIMIT=50] -->
<string name="gps_notification_found_text">Location set by GPS</string>
+
+ <!-- Title for the pseudo-notification shown when notifications are disabled (do-not-disturb
+ mode) -->
+ <string name="notifications_off_title">Notifications off</string>
+
+ <!-- Content text for do-not-disturb mode notification -->
+ <string name="notifications_off_text">Tap here to turn notifications back on.</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN-land/strings.xml b/packages/SystemUI/res/values-zh-rCN-land/strings.xml
new file mode 100644
index 0000000..0680b35
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rCN-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"屏幕已锁定为横向浏览模式。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
index 59c094e..bb70d48 100644
--- a/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"未连接至互联网"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已连接"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0cdc38d..5a74abc 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"没有最近使用的应用程序。"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"应用程序"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"蓝牙已绑定"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"配置输入法"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用物理键盘"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW-land/strings.xml b/packages/SystemUI/res/values-zh-rTW-land/strings.xml
new file mode 100644
index 0000000..df1fc39
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rTW-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="toast_rotation_locked" msgid="7609673011431556092">"螢幕現已鎖定為橫向模式"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml b/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
index 6a8ef52..67adbab 100644
--- a/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW-xlarge/strings.xml
@@ -19,8 +19,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for status_bar_clear_all_button (4722520806446512408) -->
- <skip />
+ <string name="status_bar_clear_all_button" msgid="4722520806446512408">"全部清除"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="4684094636492991496">"沒有網路連線"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="1456658018593445677">"Wi-Fi 已連線"</string>
+ <!-- no translation found for gps_notification_searching_text (894185519046488403) -->
+ <skip />
+ <!-- no translation found for gps_notification_found_text (5306445324124275852) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index c85020f..7509357 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -40,8 +40,8 @@
<string name="status_bar_settings_notifications" msgid="397146176280905137">"通知"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
<string name="recent_tasks_empty" msgid="1905484479067697884">"沒有最近用過的應用程式。"</string>
- <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
- <skip />
- <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
- <skip />
+ <string name="recent_tasks_app_label" msgid="3796483981246752469">"應用程式"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"已透過藍牙進行網際網路共用"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"設定輸入方式"</string>
+ <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用實體鍵盤"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index dfe0262..0273a4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -599,16 +599,6 @@
return (mSignalStrength != null) && !mSignalStrength.isGsm();
}
- private boolean isEvdo() {
- return ( (mServiceState != null)
- && ((mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
- }
-
private boolean hasService() {
if (mServiceState != null) {
switch (mServiceState.getState()) {
@@ -624,7 +614,6 @@
}
private final void updateSignalStrength() {
- int iconLevel = -1;
int[] iconList;
// Display signal strength while in "emergency calls only" mode
@@ -641,18 +630,6 @@
}
if (!isCdma()) {
- int asu = mSignalStrength.getGsmSignalStrength();
-
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- if (asu <= 2 || asu == 99) iconLevel = 0;
- else if (asu >= 12) iconLevel = 4;
- else if (asu >= 8) iconLevel = 3;
- else if (asu >= 5) iconLevel = 2;
- else iconLevel = 1;
-
// Though mPhone is a Manager, this call is not an IPC
if (mPhone.isNetworkRoaming()) {
iconList = sSignalImages_r[mInetCondition];
@@ -661,67 +638,11 @@
}
} else {
iconList = sSignalImages[mInetCondition];
-
- // If 3G(EV) and 1x network are available than 3G should be
- // displayed, displayed RSSI should be from the EV side.
- // If a voice call is made then RSSI should switch to 1x.
- if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
- iconLevel = getEvdoLevel();
- if (false) {
- Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level="
- + getCdmaLevel());
- }
- } else {
- iconLevel = getCdmaLevel();
- }
}
- mPhoneSignalIconId = iconList[iconLevel];
+ mPhoneSignalIconId = iconList[mSignalStrength.getLevel()];
mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
}
- private int getCdmaLevel() {
- final int cdmaDbm = mSignalStrength.getCdmaDbm();
- final int cdmaEcio = mSignalStrength.getCdmaEcio();
- int levelDbm = 0;
- int levelEcio = 0;
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- return (levelDbm < levelEcio) ? levelDbm : levelEcio;
- }
-
- private int getEvdoLevel() {
- int evdoDbm = mSignalStrength.getEvdoDbm();
- int evdoSnr = mSignalStrength.getEvdoSnr();
- int levelEvdoDbm = 0;
- int levelEvdoSnr = 0;
-
- if (evdoDbm >= -65) levelEvdoDbm = 4;
- else if (evdoDbm >= -75) levelEvdoDbm = 3;
- else if (evdoDbm >= -90) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 0;
-
- if (evdoSnr >= 7) levelEvdoSnr = 4;
- else if (evdoSnr >= 5) levelEvdoSnr = 3;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- }
-
private final void updateDataNetType(int net) {
switch (net) {
case TelephonyManager.NETWORK_TYPE_EDGE:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 42868db..317490f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -33,6 +33,11 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Telephony;
@@ -50,6 +55,7 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.server.am.BatteryStatsService;
+import com.android.internal.util.AsyncChannel;
import com.android.systemui.R;
@@ -82,6 +88,7 @@
// wifi
final WifiManager mWifiManager;
+ AsyncChannel mWifiChannel;
boolean mWifiEnabled, mWifiConnected;
int mWifiLevel;
String mWifiSsid;
@@ -140,6 +147,14 @@
// wifi
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ HandlerThread handlerThread = new HandlerThread("WifiServiceThread");
+ handlerThread.start();
+ Handler handler = new WifiHandler(handlerThread.getLooper());
+ mWifiChannel = new AsyncChannel();
+ Messenger wifiMessenger = mWifiManager.getMessenger();
+ if (wifiMessenger != null) {
+ mWifiChannel.connect(mContext, handler, wifiMessenger);
+ }
// broadcasts
IntentFilter filter = new IntentFilter();
@@ -185,6 +200,7 @@
mLabelViews.add(v);
}
+ @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
@@ -300,13 +316,6 @@
return (mSignalStrength != null) && !mSignalStrength.isGsm();
}
- private boolean isEvdo() {
- return ((mServiceState != null)
- && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
- }
-
private boolean hasService() {
if (mServiceState != null) {
switch (mServiceState.getState()) {
@@ -321,51 +330,6 @@
}
}
- private int getCdmaLevel() {
- if (mSignalStrength == null) return 0;
- final int cdmaDbm = mSignalStrength.getCdmaDbm();
- final int cdmaEcio = mSignalStrength.getCdmaEcio();
- int levelDbm = 0;
- int levelEcio = 0;
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- return (levelDbm < levelEcio) ? levelDbm : levelEcio;
- }
-
- private int getEvdoLevel() {
- if (mSignalStrength == null) return 0;
- int evdoDbm = mSignalStrength.getEvdoDbm();
- int evdoSnr = mSignalStrength.getEvdoSnr();
- int levelEvdoDbm = 0;
- int levelEvdoSnr = 0;
-
- if (evdoDbm >= -65) levelEvdoDbm = 4;
- else if (evdoDbm >= -75) levelEvdoDbm = 3;
- else if (evdoDbm >= -90) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 0;
-
- if (evdoSnr >= 7) levelEvdoSnr = 4;
- else if (evdoSnr >= 5) levelEvdoSnr = 3;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- }
-
private final void updateTelephonySignalStrength() {
// Display signal strength while in "emergency calls only" mode
if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
@@ -382,44 +346,23 @@
if (mSignalStrength == null) {
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null
- } else if (isCdma()) {
- // If 3G(EV) and 1x network are available than 3G should be
- // displayed, displayed RSSI should be from the EV side.
- // If a voice call is made then RSSI should switch to 1x.
- int iconLevel;
- if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
- iconLevel = getEvdoLevel();
- } else {
- iconLevel = getCdmaLevel();
- }
- int[] iconList;
- if (isCdmaEri()) {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
- } else {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
- }
- mPhoneSignalIconId = iconList[iconLevel];
- mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
} else {
- int asu = mSignalStrength.getGsmSignalStrength();
-
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
int iconLevel;
- if (asu <= 2 || asu == 99) iconLevel = 0;
- else if (asu >= 12) iconLevel = 4;
- else if (asu >= 8) iconLevel = 3;
- else if (asu >= 5) iconLevel = 2;
- else iconLevel = 1;
-
- // Though mPhone is a Manager, this call is not an IPC
int[] iconList;
- if (mPhone.isNetworkRoaming()) {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ iconLevel = mSignalStrength.getLevel();
+ if (isCdma()) {
+ if (isCdmaEri()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
} else {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ // Though mPhone is a Manager, this call is not an IPC
+ if (mPhone.isNetworkRoaming()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
}
mPhoneSignalIconId = iconList[iconLevel];
mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
@@ -584,6 +527,44 @@
// ===== Wifi ===================================================================
+ class WifiHandler extends Handler {
+
+ WifiHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ mWifiChannel.sendMessage(Message.obtain(this,
+ AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
+ } else {
+ Slog.e(TAG, "Failed to connect to wifi");
+ }
+ break;
+ case WifiManager.DATA_ACTIVITY_NOTIFICATION:
+ int dataActivity = msg.arg1;
+ /* TODO: update icons based on data activity */
+ switch (dataActivity) {
+ case WifiManager.DATA_ACTIVITY_IN:
+ break;
+ case WifiManager.DATA_ACTIVITY_OUT:
+ break;
+ case WifiManager.DATA_ACTIVITY_INOUT:
+ break;
+ case WifiManager.DATA_ACTIVITY_NONE:
+ break;
+ }
+ break;
+ default:
+ //Ignore
+ break;
+ }
+ }
+ }
+
private void updateWifiState(Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 86c3e75..e0d558f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -374,8 +374,9 @@
if (title != null && title.length() > 0 && icon != null) {
if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
ActivityDescription item = new ActivityDescription(
- recentInfo.thumbnail, icon, title,
- recentInfo.description, intent, id, index, info.packageName);
+ am.getTaskThumbnail(recentInfo.persistentId),
+ icon, title, recentInfo.description, intent, id,
+ index, info.packageName);
activityDescriptions.add(item);
++index;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 7a13fde..afb73a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -28,6 +28,7 @@
import android.app.StatusBarManager;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
@@ -67,6 +68,7 @@
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.Prefs;
import com.android.systemui.recent.RecentApplicationsActivity;
public class TabletStatusBar extends StatusBar implements
@@ -105,7 +107,7 @@
IWindowManager mWindowManager;
// tracking all current notifications
- private NotificationData mNotns = new NotificationData();
+ private NotificationData mNotificationData = new NotificationData();
TabletStatusBarView mStatusBarView;
View mNotificationArea;
@@ -113,6 +115,9 @@
NotificationIconArea mNotificationIconArea;
View mNavigationArea;
+ boolean mNotificationDNDMode;
+ NotificationData.Entry mNotificationDNDDummyEntry;
+
ImageView mBackButton;
View mHomeButton;
View mMenuButton;
@@ -489,25 +494,43 @@
switch (m.what) {
case MSG_OPEN_NOTIFICATION_PEEK:
if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
+
if (m.arg1 >= 0) {
- final int N = mNotns.size();
- if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
- NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
- entry.icon.setBackgroundColor(0);
- mNotificationPeekIndex = -1;
- mNotificationPeekKey = null;
+ final int N = mNotificationData.size();
+
+ if (!mNotificationDNDMode) {
+ if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
+ NotificationData.Entry entry = mNotificationData.get(N-1-mNotificationPeekIndex);
+ entry.icon.setBackgroundColor(0);
+ mNotificationPeekIndex = -1;
+ mNotificationPeekKey = null;
+ }
}
final int peekIndex = m.arg1;
if (peekIndex < N) {
//Slog.d(TAG, "loading peek: " + peekIndex);
- NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
+ NotificationData.Entry entry =
+ mNotificationDNDMode
+ ? mNotificationDNDDummyEntry
+ : mNotificationData.get(N-1-peekIndex);
NotificationData.Entry copy = new NotificationData.Entry(
entry.key,
entry.notification,
entry.icon);
inflateViews(copy, mNotificationPeekRow);
+ if (mNotificationDNDMode) {
+ copy.content.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ SharedPreferences.Editor editor = Prefs.edit(mContext);
+ editor.putBoolean(Prefs.DO_NOT_DISTURB_PREF, false);
+ editor.apply();
+ animateCollapse();
+ }
+ });
+ }
+
entry.icon.setBackgroundColor(0x20FFFFFF);
// mNotificationPeekRow.setLayoutTransition(
@@ -530,9 +553,13 @@
if (DEBUG) Slog.d(TAG, "closing notification peek window");
mNotificationPeekWindow.setVisibility(View.GONE);
mNotificationPeekRow.removeAllViews();
- final int N = mNotns.size();
+
+ final int N = mNotificationData.size();
if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
- NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
+ NotificationData.Entry entry =
+ mNotificationDNDMode
+ ? mNotificationDNDDummyEntry
+ : mNotificationData.get(N-1-mNotificationPeekIndex);
entry.icon.setBackgroundColor(0);
}
@@ -643,7 +670,7 @@
public void updateNotification(IBinder key, StatusBarNotification notification) {
if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
- final NotificationData.Entry oldEntry = mNotns.findByKey(key);
+ final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
if (oldEntry == null) {
Slog.w(TAG, "updateNotification for unknown key: " + key);
return;
@@ -781,14 +808,15 @@
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
- // synchronize with current shadow state
- mNotificationIconArea.setVisibility(View.GONE);
mTicker.halt();
} else {
Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no");
- // synchronize with current shadow state
- mNotificationIconArea.setVisibility(View.VISIBLE);
}
+ // refresh icons to show either notifications or the DND message
+ mNotificationDNDMode = Prefs.read(mContext)
+ .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
+ Slog.d(TAG, "DND: " + mNotificationDNDMode);
+ reloadAllNotificationIcons();
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
mTicker.halt();
@@ -947,7 +975,7 @@
}
private void setAreThereNotifications() {
- final boolean hasClearable = mNotns.hasClearableItems();
+ final boolean hasClearable = mNotificationData.hasClearableItems();
}
/**
@@ -1081,7 +1109,7 @@
}
StatusBarNotification removeNotificationViews(IBinder key) {
- NotificationData.Entry entry = mNotns.remove(key);
+ NotificationData.Entry entry = mNotificationData.remove(key);
if (entry == null) {
Slog.w(TAG, "removeNotification for unknown key: " + key);
return null;
@@ -1192,7 +1220,7 @@
}
// Add the icon.
- int pos = mNotns.add(entry);
+ int pos = mNotificationData.add(entry);
if (DEBUG) {
Slog.d(TAG, "addNotificationViews: added at " + pos);
}
@@ -1216,7 +1244,31 @@
final LinearLayout.LayoutParams params
= new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
- int N = mNotns.size();
+ // alternate behavior in DND mode
+ if (mNotificationDNDMode && mIconLayout.getChildCount() == 0) {
+ final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd");
+ iconView.setImageResource(R.drawable.ic_notification_dnd);
+ iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0);
+
+ final Notification dndNotification = new Notification.Builder(mContext)
+ .setContentTitle(mContext.getText(R.string.notifications_off_title))
+ .setContentText(mContext.getText(R.string.notifications_off_text))
+ .setSmallIcon(R.drawable.ic_notification_dnd)
+ .setOngoing(true)
+ .getNotification();
+
+ mNotificationDNDDummyEntry = new NotificationData.Entry(
+ null,
+ new StatusBarNotification("", 0, "", 0, 0, dndNotification),
+ iconView);
+
+ mIconLayout.addView(iconView, params);
+
+ return;
+ }
+
+ int N = mNotificationData.size();
if (DEBUG) {
Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
@@ -1231,7 +1283,7 @@
MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE : MAX_NOTIFICATION_ICONS;
for (int i=0; i< maxNotificationIconsCount; i++) {
if (i>=N) break;
- toShow.add(mNotns.get(N-i-1).icon);
+ toShow.add(mNotificationData.get(N-i-1).icon);
}
ArrayList<View> toRemove = new ArrayList<View>();
@@ -1258,12 +1310,12 @@
}
private void loadNotificationPanel() {
- int N = mNotns.size();
+ int N = mNotificationData.size();
ArrayList<View> toShow = new ArrayList<View>();
for (int i=0; i<N; i++) {
- View row = mNotns.get(N-i-1).row;
+ View row = mNotificationData.get(N-i-1).row;
toShow.add(row);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index a072aed..a8f4262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -158,7 +158,9 @@
private void advance() {
// Out with the old...
if (mCurrentView != null) {
- mWindow.removeView(mCurrentView);
+ if (mWindow != null) {
+ mWindow.removeView(mCurrentView);
+ }
mCurrentView = null;
mCurrentKey = null;
mCurrentNotification = null;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index e775dac..5ed67a9 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -26,6 +26,7 @@
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import android.media.AudioManager;
+import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
@@ -70,12 +71,12 @@
private boolean mKeyguardBypassEnabled;
- private boolean mDevicePluggedIn;
-
private boolean mDeviceProvisioned;
private int mBatteryLevel;
+ private int mBatteryStatus;
+
private CharSequence mTelephonyPlmn;
private CharSequence mTelephonySpn;
@@ -203,7 +204,7 @@
// take a guess to start
mSimState = IccCard.State.READY;
- mDevicePluggedIn = true;
+ mBatteryStatus = BATTERY_STATUS_FULL;
mBatteryLevel = 100;
mTelephonyPlmn = getDefaultPlmn();
@@ -283,13 +284,12 @@
/**
* Handle {@link #MSG_BATTERY_UPDATE}
*/
- private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) {
+ private void handleBatteryUpdate(int batteryStatus, int batteryLevel) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
- final boolean pluggedIn = isPluggedIn(pluggedInStatus);
-
- if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) {
+ if (isBatteryUpdateInteresting(batteryStatus, batteryLevel)) {
+ mBatteryStatus = batteryStatus;
mBatteryLevel = batteryLevel;
- mDevicePluggedIn = pluggedIn;
+ final boolean pluggedIn = isPluggedIn(batteryStatus);;
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onRefreshBatteryInfo(
shouldShowBatteryInfo(), pluggedIn, batteryLevel);
@@ -336,26 +336,34 @@
return status == BATTERY_STATUS_CHARGING || status == BATTERY_STATUS_FULL;
}
- private boolean isBatteryUpdateInteresting(boolean pluggedIn, int batteryLevel) {
+ private boolean isBatteryUpdateInteresting(int batteryStatus, int batteryLevel) {
// change in plug is always interesting
- if (mDevicePluggedIn != pluggedIn) {
+ final boolean isPluggedIn = isPluggedIn(batteryStatus);
+ final boolean wasPluggedIn = isPluggedIn(mBatteryStatus);
+ final boolean stateChangedWhilePluggedIn =
+ wasPluggedIn == true && isPluggedIn == true && (mBatteryStatus != batteryStatus);
+ if (wasPluggedIn != isPluggedIn || stateChangedWhilePluggedIn) {
return true;
}
// change in battery level while plugged in
- if (pluggedIn && mBatteryLevel != batteryLevel) {
+ if (isPluggedIn && mBatteryLevel != batteryLevel) {
return true;
}
- if (!pluggedIn) {
+ if (!isPluggedIn) {
// not plugged in and below threshold
- if (batteryLevel < LOW_BATTERY_THRESHOLD && batteryLevel != mBatteryLevel) {
+ if (isBatteryLow(batteryLevel) && batteryLevel != mBatteryLevel) {
return true;
}
}
return false;
}
+ private boolean isBatteryLow(int batteryLevel) {
+ return batteryLevel < LOW_BATTERY_THRESHOLD;
+ }
+
/**
* @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
* @return The string to use for the plmn, or null if it should not be shown.
@@ -485,7 +493,12 @@
}
public boolean isDevicePluggedIn() {
- return mDevicePluggedIn;
+ return isPluggedIn(mBatteryStatus);
+ }
+
+ public boolean isDeviceCharged() {
+ return mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL
+ || mBatteryLevel >= 100; // in case a particular device doesn't flag it
}
public int getBatteryLevel() {
@@ -493,7 +506,7 @@
}
public boolean shouldShowBatteryInfo() {
- return mDevicePluggedIn || mBatteryLevel < LOW_BATTERY_THRESHOLD;
+ return isPluggedIn(mBatteryStatus) || isBatteryLow(mBatteryLevel);
}
public CharSequence getTelephonyPlmn() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 7809961..b32a729 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -89,7 +89,7 @@
* This class is created by the initialization routine of the {@link WindowManagerPolicy},
* and runs on its thread. The keyguard UI is created from that thread in the
* constructor of this class. The apis may be called from other threads, including the
- * {@link com.android.server.InputManager}'s and {@link android.view.WindowManager}'s.
+ * {@link com.android.server.wm.InputManager}'s and {@link android.view.WindowManager}'s.
* Therefore, methods on this class are synchronized, and any action that is pointed
* directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
* thread of the keyguard.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 066daa8..156391e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -117,6 +117,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
+import android.view.KeyCharacterMap.FallbackAction;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.media.IAudioService;
@@ -1453,7 +1454,7 @@
}
// Check for fallback actions.
- if (kcm.getFallbackAction(keyCode, metaState, mFallbackAction)) {
+ if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
if (DEBUG_FALLBACK) {
Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
+ " metaState=" + Integer.toHexString(mFallbackAction.metaState));
@@ -1485,6 +1486,13 @@
return null;
}
+ private boolean getFallbackAction(KeyCharacterMap kcm, int keyCode, int metaState,
+ FallbackAction outFallbackAction) {
+ // Consult the key character map for specific fallback actions.
+ // For example, map NUMPAD_1 to MOVE_HOME when NUMLOCK is not pressed.
+ return kcm.getFallbackAction(keyCode, metaState, outFallbackAction);
+ }
+
/**
* A home key -> launch home action was detected. Take the appropriate action
* given the situation with the keyguard.
diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java
index da7bbb8..2aff4a8 100644
--- a/policy/src/com/android/internal/policy/impl/StatusView.java
+++ b/policy/src/com/android/internal/policy/impl/StatusView.java
@@ -51,6 +51,7 @@
private LockPatternUtils mLockPatternUtils;
private int mHelpMessageId;
private int mHelpIconId;
+ private KeyguardUpdateMonitor mUpdateMonitor;
private View findViewById(int id) {
return mView.findViewById(id);
@@ -97,6 +98,7 @@
mHasDate = (mDate != null);
mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
mLockPatternUtils = lockPatternUtils;
+ mUpdateMonitor = updateMonitor;
refreshTimeAndDateDisplay();
@@ -186,7 +188,7 @@
// Battery status
if (mPluggedIn) {
// Charging or charged
- if (mBatteryLevel >= 100) {
+ if (mUpdateMonitor.isDeviceCharged()) {
mStatus1.setText(getContext().getString(R.string.lockscreen_charged));
} else {
mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in,
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 38a896f..b31381a 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -101,12 +101,14 @@
const InputDeviceIdentifier& identifier) :
next(NULL),
fd(fd), id(id), path(path), identifier(identifier),
- classes(0), keyBitmask(NULL), configuration(NULL), virtualKeyMap(NULL) {
+ classes(0), keyBitmask(NULL), relBitmask(NULL),
+ configuration(NULL), virtualKeyMap(NULL) {
}
EventHub::Device::~Device() {
close();
delete[] keyBitmask;
+ delete[] relBitmask;
delete configuration;
delete virtualKeyMap;
}
@@ -127,9 +129,7 @@
mOpened(false), mNeedToSendFinishedDeviceScan(false),
mInputBufferIndex(0), mInputBufferCount(0), mInputFdIndex(0) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-#ifdef EV_SW
memset(mSwitches, 0, sizeof(mSwitches));
-#endif
}
EventHub::~EventHub(void) {
@@ -191,6 +191,18 @@
return OK;
}
+bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
+ if (axis >= 0 && axis <= REL_MAX) {
+ AutoMutex _l(mLock);
+
+ Device* device = getDeviceLocked(deviceId);
+ if (device && device->relBitmask) {
+ return test_bit(axis, device->relBitmask);
+ }
+ }
+ return false;
+}
+
int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
if (scanCode >= 0 && scanCode <= KEY_MAX) {
AutoMutex _l(mLock);
@@ -229,7 +241,7 @@
}
Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodes(keyCode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
@@ -253,7 +265,6 @@
}
int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
-#ifdef EV_SW
if (sw >= 0 && sw <= SW_MAX) {
AutoMutex _l(mLock);
@@ -262,7 +273,6 @@
return getSwitchStateLocked(device, sw);
}
}
-#endif
return AKEY_STATE_UNKNOWN;
}
@@ -297,7 +307,8 @@
for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
scanCodes.clear();
- status_t err = device->keyMap.keyLayoutMap->findScanCodes(keyCodes[codeIndex], &scanCodes);
+ status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey(
+ keyCodes[codeIndex], &scanCodes);
if (! err) {
// check the possible scan codes identified by the layout map against the
// map of codes actually emitted by the driver
@@ -312,14 +323,14 @@
return true;
}
-status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
+status_t EventHub::mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const
{
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
+ status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -329,7 +340,7 @@
device = getDeviceLocked(mBuiltInKeyboardId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
+ status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -341,6 +352,34 @@
return NAME_NOT_FOUND;
}
+status_t EventHub::mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const
+{
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ if (err == NO_ERROR) {
+ return NO_ERROR;
+ }
+ }
+
+ if (mBuiltInKeyboardId != -1) {
+ device = getDeviceLocked(mBuiltInKeyboardId);
+
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ if (err == NO_ERROR) {
+ return NO_ERROR;
+ }
+ }
+ }
+
+ *outAxis = -1;
+ return NAME_NOT_FOUND;
+}
+
void EventHub::addExcludedDevice(const char* deviceName)
{
AutoMutex _l(mLock);
@@ -488,7 +527,7 @@
if (iev.type == EV_KEY) {
outEvent->keyCode = AKEYCODE_UNKNOWN;
if (device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(iev.code,
+ status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code,
&outEvent->keyCode, &outEvent->flags);
LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
iev.code, outEvent->keyCode, outEvent->flags, err);
@@ -731,86 +770,89 @@
loadConfiguration(device);
// Figure out the kinds of events the device reports.
-
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
- LOGV("Getting keys...");
- if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
- //LOGI("MAP\n");
- //for (int i = 0; i < sizeof(key_bitmask); i++) {
- // LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
- //}
+ uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
+ memset(abs_bitmask, 0, sizeof(abs_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
- // See if this is a keyboard. Ignore everything in the button range except for
- // joystick and gamepad buttons which are also considered keyboards.
- if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
- || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_JOYSTICK),
- sizeof_bit_array(BTN_DIGI))
- || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
- sizeof_bit_array(KEY_MAX + 1))) {
- device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+ uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
+ memset(rel_bitmask, 0, sizeof(rel_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
- device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
- if (device->keyBitmask != NULL) {
- memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
- } else {
- delete device;
- LOGE("out of memory allocating key bitmask");
- return -1;
- }
- }
+ uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
+ memset(sw_bitmask, 0, sizeof(sw_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask);
+
+ device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
+ if (device->keyBitmask != NULL) {
+ memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
+ } else {
+ delete device;
+ LOGE("out of memory allocating key bitmask");
+ return -1;
}
-
+
+ device->relBitmask = new uint8_t[sizeof(rel_bitmask)];
+ if (device->relBitmask != NULL) {
+ memcpy(device->relBitmask, rel_bitmask, sizeof(rel_bitmask));
+ } else {
+ delete device;
+ LOGE("out of memory allocating rel bitmask");
+ return -1;
+ }
+
+ // See if this is a keyboard. Ignore everything in the button range except for
+ // joystick and gamepad buttons which are handled like keyboards for the most part.
+ bool haveKeyboardKeys = containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
+ || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
+ sizeof_bit_array(KEY_MAX + 1));
+ bool haveGamepadButtons =containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_JOYSTICK),
+ sizeof_bit_array(BTN_DIGI));
+ if (haveKeyboardKeys || haveGamepadButtons) {
+ device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+ }
+
// See if this is a cursor device such as a trackball or mouse.
- if (test_bit(BTN_MOUSE, key_bitmask)) {
- uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
- memset(rel_bitmask, 0, sizeof(rel_bitmask));
- LOGV("Getting relative controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) {
- if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_CURSOR;
- }
- }
+ if (test_bit(BTN_MOUSE, key_bitmask)
+ && test_bit(REL_X, rel_bitmask)
+ && test_bit(REL_Y, rel_bitmask)) {
+ device->classes |= INPUT_DEVICE_CLASS_CURSOR;
}
// See if this is a touch pad.
- uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
- memset(abs_bitmask, 0, sizeof(abs_bitmask));
- LOGV("Getting absolute controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
- // Is this a new modern multi-touch driver?
- if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
- && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+ // Is this a new modern multi-touch driver?
+ if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
+ && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+ // Some joysticks such as the PS3 controller report axes that conflict
+ // with the ABS_MT range. Try to confirm that the device really is
+ // a touch screen.
+ if (test_bit(BTN_TOUCH, key_bitmask) || !haveGamepadButtons) {
device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
-
- // Is this an old style single-touch driver?
- } else if (test_bit(BTN_TOUCH, key_bitmask)
- && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_TOUCH;
}
+ // Is this an old style single-touch driver?
+ } else if (test_bit(BTN_TOUCH, key_bitmask)
+ && test_bit(ABS_X, abs_bitmask)
+ && test_bit(ABS_Y, abs_bitmask)) {
+ device->classes |= INPUT_DEVICE_CLASS_TOUCH;
}
-#ifdef EV_SW
// figure out the switches this device reports
- uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
- memset(sw_bitmask, 0, sizeof(sw_bitmask));
- bool hasSwitches = false;
- if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
- for (int i=0; i<EV_SW; i++) {
- //LOGI("Device %d sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
- if (test_bit(i, sw_bitmask)) {
- hasSwitches = true;
- if (mSwitches[i] == 0) {
- mSwitches[i] = device->id;
- }
+ bool haveSwitches = false;
+ for (int i=0; i<EV_SW; i++) {
+ //LOGI("Device %d sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
+ if (test_bit(i, sw_bitmask)) {
+ haveSwitches = true;
+ if (mSwitches[i] == 0) {
+ mSwitches[i] = device->id;
}
}
}
- if (hasSwitches) {
+ if (haveSwitches) {
device->classes |= INPUT_DEVICE_CLASS_SWITCH;
}
-#endif
if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
// Load the virtual keys for the touch screen, if any.
@@ -862,12 +904,10 @@
// See if this device is a joystick.
// Ignore touchscreens because they use the same absolute axes for other purposes.
+ // Assumes that joysticks always have buttons and the keymap has been loaded.
if (device->classes & INPUT_DEVICE_CLASS_GAMEPAD
&& !(device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
- if (test_bit(ABS_X, abs_bitmask)
- || test_bit(ABS_Y, abs_bitmask)
- || test_bit(ABS_HAT0X, abs_bitmask)
- || test_bit(ABS_HAT0Y, abs_bitmask)) {
+ if (containsNonZeroByte(abs_bitmask, 0, sizeof_bit_array(ABS_MAX + 1))) {
device->classes |= INPUT_DEVICE_CLASS_JOYSTICK;
}
}
@@ -950,7 +990,7 @@
}
Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodes(keycode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
const size_t N = scanCodes.size();
for (size_t i=0; i<N && i<=KEY_MAX; i++) {
int32_t sc = scanCodes.itemAt(i);
@@ -972,13 +1012,11 @@
device->path.string(), device->identifier.name.string(), device->id,
device->fd, device->classes);
-#ifdef EV_SW
for (int j=0; j<EV_SW; j++) {
if (mSwitches[j] == device->id) {
mSwitches[j] = 0;
}
}
-#endif
if (device->id == mBuiltInKeyboardId) {
LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 52993f7..23bb344 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -167,9 +167,14 @@
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const = 0;
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const = 0;
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const = 0;
+
// exclude a particular device from opening
// this can be used to ignore input devices for sensors
virtual void addExcludedDevice(const char* deviceName) = 0;
@@ -221,9 +226,14 @@
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const;
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const;
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const;
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const;
+
virtual void addExcludedDevice(const char* deviceName);
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
@@ -266,6 +276,7 @@
uint32_t classes;
uint8_t* keyBitmask;
+ uint8_t* relBitmask;
String8 configurationFile;
PropertyMap* configuration;
VirtualKeyMap* virtualKeyMap;
@@ -314,9 +325,7 @@
List<String8> mExcludedDevices;
// device ids that report particular switches.
-#ifdef EV_SW
int32_t mSwitches[SW_MAX + 1];
-#endif
static const int INPUT_BUFFER_SIZE = 64;
struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index cbfdd75..ef984d4 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -115,6 +115,7 @@
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_MOVE:
case AMOTION_EVENT_ACTION_OUTSIDE:
+ case AMOTION_EVENT_ACTION_HOVER_MOVE:
return true;
case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_POINTER_UP: {
@@ -318,7 +319,8 @@
uint32_t source = motionEntry->source;
if (! isAppSwitchDue
&& motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
- && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
+ && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
+ || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& deviceId == mThrottleState.lastDeviceId
&& source == mThrottleState.lastSource) {
nsecs_t nextTime = mThrottleState.lastEventTime
@@ -478,12 +480,15 @@
// If the application takes too long to catch up then we drop all events preceding
// the touch into the other window.
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
+ if ((motionEntry->action == AMOTION_EVENT_ACTION_DOWN
+ || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
&& mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
&& mInputTargetWaitApplication != NULL) {
- int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].x);
- int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].y);
+ int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
+ getAxisValue(AMOTION_EVENT_AXIS_X));
+ int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
if (touchedWindow
&& touchedWindow->inputWindowHandle != NULL
@@ -836,12 +841,13 @@
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
// Identify targets.
+ bool conflictingPointerActions = false;
if (! mCurrentInputTargetsValid) {
int32_t injectionResult;
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime,
- entry, nextWakeupTime);
+ entry, nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime,
@@ -861,6 +867,10 @@
}
// Dispatch the motion.
+ if (conflictingPointerActions) {
+ synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CANCEL_POINTER_EVENTS, "Conflicting pointer actions.");
+ }
dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
return true;
}
@@ -888,11 +898,15 @@
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
i, entry->pointerIds[i],
- sample->pointerCoords[i].x, sample->pointerCoords[i].y,
- sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
- sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
- sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
- sample->pointerCoords[i].orientation);
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
// Keep in mind that due to batching, it is possible for the number of samples actually
@@ -1117,7 +1131,7 @@
}
int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
- const MotionEntry* entry, nsecs_t* nextWakeupTime) {
+ const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
enum InjectionPermission {
INJECTION_PERMISSION_UNKNOWN,
INJECTION_PERMISSION_GRANTED,
@@ -1160,36 +1174,45 @@
// Update the touch state as needed based on the properties of the touch event.
int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- bool isSplit, wrongDevice;
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- mTempTouchState.reset();
- mTempTouchState.down = true;
- mTempTouchState.deviceId = entry->deviceId;
- mTempTouchState.source = entry->source;
- isSplit = false;
- wrongDevice = false;
+
+ bool isSplit = mTouchState.split;
+ bool wrongDevice = mTouchState.down
+ && (mTouchState.deviceId != entry->deviceId
+ || mTouchState.source != entry->source);
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
+ if (wrongDevice && !down) {
+ mTempTouchState.copyFrom(mTouchState);
+ } else {
+ mTempTouchState.reset();
+ mTempTouchState.down = down;
+ mTempTouchState.deviceId = entry->deviceId;
+ mTempTouchState.source = entry->source;
+ isSplit = false;
+ wrongDevice = false;
+ }
} else {
mTempTouchState.copyFrom(mTouchState);
- isSplit = mTempTouchState.split;
- wrongDevice = mTempTouchState.down
- && (mTempTouchState.deviceId != entry->deviceId
- || mTempTouchState.source != entry->source);
- if (wrongDevice) {
+ }
+ if (wrongDevice) {
#if DEBUG_INPUT_DISPATCHER_POLICY
- LOGD("Dropping event because a pointer for a different device is already down.");
+ LOGD("Dropping event because a pointer for a different device is already down.");
#endif
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
+ injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ goto Failed;
}
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
+ || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
/* Case 1: New splittable pointer going down. */
int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
- int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
+ int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
+ getAxisValue(AMOTION_EVENT_AXIS_X));
+ int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
const InputWindow* newTouchedWindow = NULL;
const InputWindow* topErrorWindow = NULL;
@@ -1357,7 +1380,8 @@
// If this is the first pointer going down and the touched window has a wallpaper
// then also add the touched wallpaper windows so they are locked in for the duration
// of the touch gesture.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
if (foregroundWindow->hasWallpaper) {
for (size_t i = 0; i < mWindows.size(); i++) {
@@ -1396,12 +1420,14 @@
if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
if (!wrongDevice) {
if (maskedAction == AMOTION_EVENT_ACTION_UP
- || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ || maskedAction == AMOTION_EVENT_ACTION_CANCEL
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// All pointers up or canceled.
mTempTouchState.reset();
} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
// First pointer went down.
if (mTouchState.down) {
+ *outConflictingPointerActions = true;
#if DEBUG_FOCUS
LOGD("Pointer down received while already down.");
#endif
@@ -1742,29 +1768,7 @@
// Update the connection's input state.
EventEntry* eventEntry = dispatchEntry->eventEntry;
- InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
-
-#if FILTER_INPUT_EVENTS
- // Filter out inconsistent sequences of input events.
- // The input system may drop or inject events in a way that could violate implicit
- // invariants on input state and potentially cause an application to crash
- // or think that a key or pointer is stuck down. Technically we make no guarantees
- // of consistency but it would be nice to improve on this where possible.
- // XXX: This code is a proof of concept only. Not ready for prime time.
- if (consistency == InputState::TOLERABLE) {
-#if DEBUG_DISPATCH_CYCLE
- LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
- "current input state but that is likely to be tolerated by the application.",
- connection->getInputChannelName());
-#endif
- } else if (consistency == InputState::BROKEN) {
- LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
- "current input state and that is likely to cause the application to crash.",
- connection->getInputChannelName());
- startNextDispatchCycleLocked(currentTime, connection);
- return;
- }
-#endif
+ connection->inputState.trackEvent(eventEntry);
// Publish the event.
status_t status;
@@ -2275,11 +2279,16 @@
LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
- i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
- pointerCoords[i].pressure, pointerCoords[i].size,
- pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
- pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
- pointerCoords[i].orientation);
+ i, pointerIds[i],
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
#endif
if (! validateMotionEvent(action, pointerCount, pointerIds)) {
@@ -2294,7 +2303,8 @@
AutoMutex _l(mLock);
// Attempt batching and streaming of move events.
- if (action == AMOTION_EVENT_ACTION_MOVE) {
+ if (action == AMOTION_EVENT_ACTION_MOVE
+ || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// BATCHING CASE
//
// Try to append a move sample to the tail of the inbound queue for this device.
@@ -2313,7 +2323,7 @@
continue;
}
- if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+ if (motionEntry->action != action
|| motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
|| motionEntry->isInjected()) {
@@ -2372,7 +2382,7 @@
MotionEntry* motionEntry = static_cast<MotionEntry*>(
dispatchEntry->eventEntry);
- if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+ if (motionEntry->action != action
|| motionEntry->deviceId != deviceId
|| motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
@@ -3516,21 +3526,20 @@
return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
+void InputDispatcher::InputState::trackEvent(
const EventEntry* entry) {
switch (entry->type) {
case EventEntry::TYPE_KEY:
- return trackKey(static_cast<const KeyEntry*>(entry));
+ trackKey(static_cast<const KeyEntry*>(entry));
+ break;
case EventEntry::TYPE_MOTION:
- return trackMotion(static_cast<const MotionEntry*>(entry));
-
- default:
- return CONSISTENT;
+ trackMotion(static_cast<const MotionEntry*>(entry));
+ break;
}
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
+void InputDispatcher::InputState::trackKey(
const KeyEntry* entry) {
int32_t action = entry->action;
for (size_t i = 0; i < mKeyMementos.size(); i++) {
@@ -3542,19 +3551,20 @@
switch (action) {
case AKEY_EVENT_ACTION_UP:
mKeyMementos.removeAt(i);
- return CONSISTENT;
+ return;
case AKEY_EVENT_ACTION_DOWN:
- return TOLERABLE;
+ mKeyMementos.removeAt(i);
+ goto Found;
default:
- return BROKEN;
+ return;
}
}
}
- switch (action) {
- case AKEY_EVENT_ACTION_DOWN: {
+Found:
+ if (action == AKEY_EVENT_ACTION_DOWN) {
mKeyMementos.push();
KeyMemento& memento = mKeyMementos.editTop();
memento.deviceId = entry->deviceId;
@@ -3563,15 +3573,10 @@
memento.scanCode = entry->scanCode;
memento.flags = entry->flags;
memento.downTime = entry->downTime;
- return CONSISTENT;
- }
-
- default:
- return BROKEN;
}
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
+void InputDispatcher::InputState::trackMotion(
const MotionEntry* entry) {
int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
for (size_t i = 0; i < mMotionMementos.size(); i++) {
@@ -3581,40 +3586,28 @@
switch (action) {
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
+ case AMOTION_EVENT_ACTION_HOVER_MOVE:
mMotionMementos.removeAt(i);
- return CONSISTENT;
+ return;
case AMOTION_EVENT_ACTION_DOWN:
- return TOLERABLE;
-
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- if (entry->pointerCount == memento.pointerCount + 1) {
- memento.setPointers(entry);
- return CONSISTENT;
- }
- return BROKEN;
+ mMotionMementos.removeAt(i);
+ goto Found;
case AMOTION_EVENT_ACTION_POINTER_UP:
- if (entry->pointerCount == memento.pointerCount - 1) {
- memento.setPointers(entry);
- return CONSISTENT;
- }
- return BROKEN;
-
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_MOVE:
- if (entry->pointerCount == memento.pointerCount) {
- return CONSISTENT;
- }
- return BROKEN;
+ memento.setPointers(entry);
+ return;
default:
- return BROKEN;
+ return;
}
}
}
- switch (action) {
- case AMOTION_EVENT_ACTION_DOWN: {
+Found:
+ if (action == AMOTION_EVENT_ACTION_DOWN) {
mMotionMementos.push();
MotionMemento& memento = mMotionMementos.editTop();
memento.deviceId = entry->deviceId;
@@ -3623,11 +3616,6 @@
memento.yPrecision = entry->yPrecision;
memento.downTime = entry->downTime;
memento.setPointers(entry);
- return CONSISTENT;
- }
-
- default:
- return BROKEN;
}
}
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 006c6b8..7abe014 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -593,19 +593,6 @@
* synthesized when events are dropped. */
class InputState {
public:
- // Specifies whether a given event will violate input state consistency.
- enum Consistency {
- // The event is consistent with the current input state.
- CONSISTENT,
- // The event is inconsistent with the current input state but applications
- // will tolerate it. eg. Down followed by another down.
- TOLERABLE,
- // The event is inconsistent with the current input state and will probably
- // cause applications to crash. eg. Up without prior down, move with
- // unexpected number of pointers.
- BROKEN
- };
-
// Specifies the sources to cancel.
enum CancelationOptions {
CANCEL_ALL_EVENTS = 0,
@@ -621,16 +608,13 @@
bool isNeutral() const;
// Records tracking information for an event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackEvent(const EventEntry* entry);
+ void trackEvent(const EventEntry* entry);
// Records tracking information for a key event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackKey(const KeyEntry* entry);
+ void trackKey(const KeyEntry* entry);
// Records tracking information for a motion event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackMotion(const MotionEntry* entry);
+ void trackMotion(const MotionEntry* entry);
// Synthesizes cancelation events for the current state and resets the tracked state.
void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
@@ -911,7 +895,7 @@
int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
nsecs_t* nextWakeupTime);
int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
- nsecs_t* nextWakeupTime);
+ nsecs_t* nextWakeupTime, bool* outConflictingPointerActions);
void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
BitSet32 pointerIds);
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index a4d5f35..a963c72 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -565,15 +565,6 @@
mMappers.clear();
}
-static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo,
- int32_t rangeType, const char* name) {
- const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType);
- if (range) {
- dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
- name, range->min, range->max, range->flat, range->fuzz);
- }
-}
-
void InputDevice::dump(String8& dump) {
InputDeviceInfo deviceInfo;
getDeviceInfo(& deviceInfo);
@@ -582,17 +573,24 @@
deviceInfo.getName().string());
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
- if (!deviceInfo.getMotionRanges().isEmpty()) {
+
+ const KeyedVector<int32_t, InputDeviceInfo::MotionRange> ranges = deviceInfo.getMotionRanges();
+ if (!ranges.isEmpty()) {
dump.append(INDENT2 "Motion Ranges:\n");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation");
+ for (size_t i = 0; i < ranges.size(); i++) {
+ int32_t axis = ranges.keyAt(i);
+ const char* label = getAxisLabel(axis);
+ char name[32];
+ if (label) {
+ strncpy(name, label, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ } else {
+ snprintf(name, sizeof(name), "%d", axis);
+ }
+ const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+ dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
+ name, range.min, range.max, range.flat, range.fuzz);
+ }
}
size_t numMappers = mMappers.size();
@@ -1061,14 +1059,21 @@
if (mParameters.mode == Parameters::MODE_POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AINPUT_MOTION_RANGE_X, minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, minY, maxY, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, minY, maxY, 0.0f, 0.0f);
}
} else {
- info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, -1.0f, 1.0f, 0.0f, mXScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, -1.0f, 1.0f, 0.0f, mYScale);
}
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
+
+ if (mHaveVWheel) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
+ }
+ if (mHaveHWheel) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
+ }
}
void CursorInputMapper::dump(String8& dump) {
@@ -1076,8 +1081,14 @@
AutoMutex _l(mLock);
dump.append(INDENT2 "Cursor Input Mapper:\n");
dumpParameters(dump);
+ dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT3 "HaveVWheel: %s\n", toString(mHaveVWheel));
+ dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel));
+ dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+ dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
} // release lock
@@ -1107,6 +1118,12 @@
mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
break;
}
+
+ mVWheelScale = 1.0f;
+ mHWheelScale = 1.0f;
+
+ mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
+ mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
}
void CursorInputMapper::configureParameters() {
@@ -1200,6 +1217,14 @@
mAccumulator.fields |= Accumulator::FIELD_REL_Y;
mAccumulator.relY = rawEvent->value;
break;
+ case REL_WHEEL:
+ mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL;
+ mAccumulator.relWheel = rawEvent->value;
+ break;
+ case REL_HWHEEL:
+ mAccumulator.fields |= Accumulator::FIELD_REL_HWHEEL;
+ mAccumulator.relHWheel = rawEvent->value;
+ break;
}
break;
@@ -1250,8 +1275,10 @@
if (downChanged) {
motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else {
+ } else if (mLocked.down || mPointerController == NULL) {
motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ } else {
+ motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
}
if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
@@ -1285,24 +1312,30 @@
}
}
+ pointerCoords.clear();
+
if (mPointerController != NULL) {
mPointerController->move(deltaX, deltaY);
if (downChanged) {
mPointerController->setButtonState(mLocked.down ? POINTER_BUTTON_1 : 0);
}
- mPointerController->getPosition(&pointerCoords.x, &pointerCoords.y);
+ float x, y;
+ mPointerController->getPosition(&x, &y);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
} else {
- pointerCoords.x = deltaX;
- pointerCoords.y = deltaY;
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
}
- pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
- pointerCoords.size = 0;
- pointerCoords.touchMajor = 0;
- pointerCoords.touchMinor = 0;
- pointerCoords.toolMajor = 0;
- pointerCoords.toolMinor = 0;
- pointerCoords.orientation = 0;
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
+
+ if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mAccumulator.relWheel);
+ }
+ if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mAccumulator.relHWheel);
+ }
} // release lock
int32_t metaState = mContext->getGlobalMetaState();
@@ -1351,35 +1384,35 @@
// noticed immediately.
configureSurfaceLocked();
- info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y);
if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
mLocked.orientedRanges.pressure);
}
if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+ info->addMotionRange(AMOTION_EVENT_AXIS_SIZE,
mLocked.orientedRanges.size);
}
if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
mLocked.orientedRanges.touchMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR,
mLocked.orientedRanges.touchMinor);
}
if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR,
mLocked.orientedRanges.toolMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR,
mLocked.orientedRanges.toolMinor);
}
if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+ info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION,
mLocked.orientedRanges.orientation);
}
} // release lock
@@ -1804,7 +1837,7 @@
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
uint32_t flags;
- if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+ if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode,
& keyCode, & flags)) {
LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
@@ -2641,9 +2674,11 @@
int32_t c2 = signExtendNybble(in.orientation & 0x0f);
if (c1 != 0 || c2 != 0) {
orientation = atan2f(c1, c2) * 0.5f;
- float minorAxisScale = (16.0f - pythag(c1, c2)) / 16.0f;
- toolMinor *= minorAxisScale;
- touchMinor *= minorAxisScale;
+ float scale = 1.0f + pythag(c1, c2) / 16.0f;
+ touchMajor *= scale;
+ touchMinor /= scale;
+ toolMajor *= scale;
+ toolMinor /= scale;
} else {
orientation = 0;
}
@@ -2684,15 +2719,16 @@
// Write output coords.
PointerCoords& out = pointerCoords[outIndex];
- out.x = x;
- out.y = y;
- out.pressure = pressure;
- out.size = size;
- out.touchMajor = touchMajor;
- out.touchMinor = touchMinor;
- out.toolMajor = toolMajor;
- out.toolMinor = toolMinor;
- out.orientation = orientation;
+ out.clear();
+ out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
+ out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
pointerIds[outIndex] = int32_t(id);
@@ -2704,14 +2740,17 @@
// Check edge flags by looking only at the first pointer since the flags are
// global to the event.
if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- if (pointerCoords[0].x <= 0) {
+ float x = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
+ float y = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
+
+ if (x <= 0) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
- } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+ } else if (x >= mLocked.orientedSurfaceWidth) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
}
- if (pointerCoords[0].y <= 0) {
+ if (y <= 0) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
- } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+ } else if (y >= mLocked.orientedSurfaceHeight) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
}
}
@@ -3710,7 +3749,6 @@
JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
InputMapper(device) {
- initialize();
}
JoystickInputMapper::~JoystickInputMapper() {
@@ -3723,182 +3761,219 @@
void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- if (mAxes.x.valid) {
- info->addMotionRange(AINPUT_MOTION_RANGE_X,
- mAxes.x.min, mAxes.x.max, mAxes.x.flat, mAxes.x.fuzz);
- }
- if (mAxes.y.valid) {
- info->addMotionRange(AINPUT_MOTION_RANGE_Y,
- mAxes.y.min, mAxes.y.max, mAxes.y.flat, mAxes.y.fuzz);
+ for (size_t i = 0; i < mAxes.size(); i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ info->addMotionRange(axis.axis, axis.min, axis.max, axis.flat, axis.fuzz);
}
}
void JoystickInputMapper::dump(String8& dump) {
dump.append(INDENT2 "Joystick Input Mapper:\n");
- dump.append(INDENT3 "Raw Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
-
- dump.append(INDENT3 "Normalized Axes:\n");
- dumpNormalizedAxis(dump, mAxes.x, "X");
- dumpNormalizedAxis(dump, mAxes.y, "Y");
- dumpNormalizedAxis(dump, mAxes.hat0X, "Hat0X");
- dumpNormalizedAxis(dump, mAxes.hat0Y, "Hat0Y");
-}
-
-void JoystickInputMapper::dumpNormalizedAxis(String8& dump,
- const NormalizedAxis& axis, const char* name) {
- if (axis.valid) {
+ dump.append(INDENT3 "Axes:\n");
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ const char* label = getAxisLabel(axis.axis);
+ char name[32];
+ if (label) {
+ strncpy(name, label, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ } else {
+ snprintf(name, sizeof(name), "%d", axis.axis);
+ }
dump.appendFormat(INDENT4 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, "
- "scale=%0.3f, center=%0.3f, precision=%0.3f, value=%0.3f\n",
+ "scale=%0.3f, offset=%0.3f\n",
name, axis.min, axis.max, axis.flat, axis.fuzz,
- axis.scale, axis.center, axis.precision, axis.value);
- } else {
- dump.appendFormat(INDENT4 "%s: unknown range\n", name);
+ axis.scale, axis.offset);
+ dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
+ mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
+ axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
}
}
void JoystickInputMapper::configure() {
InputMapper::configure();
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_HAT0X, & mRawAxes.hat0X);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_HAT0Y, & mRawAxes.hat0Y);
+ // Collect all axes.
+ for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
+ RawAbsoluteAxisInfo rawAxisInfo;
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ if (rawAxisInfo.valid) {
+ int32_t axisId;
+ bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisId);
+ if (!explicitlyMapped) {
+ // Axis is not explicitly mapped, will choose a generic axis later.
+ axisId = -1;
+ }
- mAxes.x.configure(mRawAxes.x);
- mAxes.y.configure(mRawAxes.y);
- mAxes.hat0X.configure(mRawAxes.hat0X);
- mAxes.hat0Y.configure(mRawAxes.hat0Y);
+ Axis axis;
+ if (isCenteredAxis(axisId)) {
+ float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
+ axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
+ scale, offset, -1.0f, 1.0f,
+ rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ } else {
+ float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
+ scale, 0.0f, 0.0f, 1.0f,
+ rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ }
+
+ // To eliminate noise while the joystick is at rest, filter out small variations
+ // in axis values up front.
+ axis.filter = axis.flat * 0.25f;
+
+ mAxes.add(abs, axis);
+ }
+ }
+
+ // If there are too many axes, start dropping them.
+ // Prefer to keep explicitly mapped axes.
+ if (mAxes.size() > PointerCoords::MAX_AXES) {
+ LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
+ getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
+ pruneAxes(true);
+ pruneAxes(false);
+ }
+
+ // Assign generic axis ids to remaining axes.
+ int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ if (axis.axis < 0) {
+ while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
+ && haveAxis(nextGenericAxisId)) {
+ nextGenericAxisId += 1;
+ }
+
+ if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
+ axis.axis = nextGenericAxisId;
+ nextGenericAxisId += 1;
+ } else {
+ LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
+ "have already been assigned to other axes.",
+ getDeviceName().string(), mAxes.keyAt(i));
+ mAxes.removeItemsAt(i--);
+ numAxes -= 1;
+ }
+ }
+ }
}
-void JoystickInputMapper::initialize() {
- mAccumulator.clear();
+bool JoystickInputMapper::haveAxis(int32_t axis) {
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ if (mAxes.valueAt(i).axis == axis) {
+ return true;
+ }
+ }
+ return false;
+}
- mAxes.x.resetState();
- mAxes.y.resetState();
- mAxes.hat0X.resetState();
- mAxes.hat0Y.resetState();
+void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
+ size_t i = mAxes.size();
+ while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
+ if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
+ continue;
+ }
+ LOGI("Discarding joystick '%s' axis %d because there are too many axes.",
+ getDeviceName().string(), mAxes.keyAt(i));
+ mAxes.removeItemsAt(i);
+ }
+}
+
+bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
+ switch (axis) {
+ case AMOTION_EVENT_AXIS_X:
+ case AMOTION_EVENT_AXIS_Y:
+ case AMOTION_EVENT_AXIS_Z:
+ case AMOTION_EVENT_AXIS_RX:
+ case AMOTION_EVENT_AXIS_RY:
+ case AMOTION_EVENT_AXIS_RZ:
+ case AMOTION_EVENT_AXIS_HAT_X:
+ case AMOTION_EVENT_AXIS_HAT_Y:
+ case AMOTION_EVENT_AXIS_ORIENTATION:
+ return true;
+ default:
+ return false;
+ }
}
void JoystickInputMapper::reset() {
// Recenter all axes.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mAccumulator.clear();
- mAccumulator.fields = Accumulator::FIELD_ALL;
- sync(when);
- // Reinitialize state.
- initialize();
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ axis.newValue = 0;
+ }
+
+ sync(when, true /*force*/);
InputMapper::reset();
}
void JoystickInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
- case EV_ABS:
- switch (rawEvent->scanCode) {
- case ABS_X:
- mAccumulator.fields |= Accumulator::FIELD_ABS_X;
- mAccumulator.absX = rawEvent->value;
- break;
- case ABS_Y:
- mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
- mAccumulator.absY = rawEvent->value;
- break;
- case ABS_HAT0X:
- mAccumulator.fields |= Accumulator::FIELD_ABS_HAT0X;
- mAccumulator.absHat0X = rawEvent->value;
- break;
- case ABS_HAT0Y:
- mAccumulator.fields |= Accumulator::FIELD_ABS_HAT0Y;
- mAccumulator.absHat0Y = rawEvent->value;
- break;
+ case EV_ABS: {
+ ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
+ if (index >= 0) {
+ Axis& axis = mAxes.editValueAt(index);
+ float newValue = rawEvent->value * axis.scale + axis.offset;
+ if (newValue != axis.newValue) {
+ axis.newValue = newValue;
+ }
}
break;
+ }
case EV_SYN:
switch (rawEvent->scanCode) {
case SYN_REPORT:
- sync(rawEvent->when);
+ sync(rawEvent->when, false /*force*/);
break;
}
break;
}
}
-void JoystickInputMapper::sync(nsecs_t when) {
- uint32_t fields = mAccumulator.fields;
- if (fields == 0) {
- return; // no new state changes, so nothing to do
+void JoystickInputMapper::sync(nsecs_t when, bool force) {
+ if (!force && !haveAxesChangedSignificantly()) {
+ return;
}
int32_t metaState = mContext->getGlobalMetaState();
- bool motionAxisChanged = false;
- if (fields & Accumulator::FIELD_ABS_X) {
- if (mAxes.x.updateValue(mAccumulator.absX)) {
- motionAxisChanged = true;
- }
+ PointerCoords pointerCoords;
+ pointerCoords.clear();
+
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ pointerCoords.setAxisValue(axis.axis, axis.newValue);
+ axis.oldValue = axis.newValue;
}
- if (fields & Accumulator::FIELD_ABS_Y) {
- if (mAxes.y.updateValue(mAccumulator.absY)) {
- motionAxisChanged = true;
- }
- }
-
- if (motionAxisChanged) {
- PointerCoords pointerCoords;
- pointerCoords.x = mAxes.x.value;
- pointerCoords.y = mAxes.y.value;
- pointerCoords.touchMajor = 0;
- pointerCoords.touchMinor = 0;
- pointerCoords.toolMajor = 0;
- pointerCoords.toolMinor = 0;
- pointerCoords.pressure = 0;
- pointerCoords.size = 0;
- pointerCoords.orientation = 0;
-
- int32_t pointerId = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerId, &pointerCoords, mAxes.x.precision, mAxes.y.precision, 0);
- }
-
- if (fields & Accumulator::FIELD_ABS_HAT0X) {
- if (mAxes.hat0X.updateValueAndDirection(mAccumulator.absHat0X)) {
- notifyDirectionalAxis(mAxes.hat0X, when, metaState,
- AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT);
- }
- }
-
- if (fields & Accumulator::FIELD_ABS_HAT0Y) {
- if (mAxes.hat0Y.updateValueAndDirection(mAccumulator.absHat0Y)) {
- notifyDirectionalAxis(mAxes.hat0Y, when, metaState,
- AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN);
- }
- }
-
- mAccumulator.clear();
+ int32_t pointerId = 0;
+ getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
+ AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerId, &pointerCoords, 0, 0, 0);
}
-void JoystickInputMapper::notifyDirectionalAxis(DirectionalAxis& axis,
- nsecs_t when, int32_t metaState, int32_t lowKeyCode, int32_t highKeyCode) {
- if (axis.lastKeyCode) {
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_FROM_SYSTEM,
- axis.lastKeyCode, 0, metaState, when);
- axis.lastKeyCode = 0;
+bool JoystickInputMapper::haveAxesChangedSignificantly() {
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ if (axis.newValue != axis.oldValue
+ && fabs(axis.newValue - axis.oldValue) > axis.filter) {
+ return true;
+ }
}
- if (axis.direction) {
- axis.lastKeyCode = axis.direction > 0 ? highKeyCode : lowKeyCode;
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AKEY_EVENT_ACTION_DOWN, AKEY_EVENT_FLAG_FROM_SYSTEM,
- axis.lastKeyCode, 0, metaState, when);
- }
+ return false;
}
-
} // namespace android
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 27cb8e1..cf41535 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -481,7 +481,9 @@
enum {
FIELD_BTN_MOUSE = 1,
FIELD_REL_X = 2,
- FIELD_REL_Y = 4
+ FIELD_REL_Y = 4,
+ FIELD_REL_WHEEL = 8,
+ FIELD_REL_HWHEEL = 16,
};
uint32_t fields;
@@ -489,6 +491,8 @@
bool btnMouse;
int32_t relX;
int32_t relY;
+ int32_t relWheel;
+ int32_t relHWheel;
inline void clear() {
fields = 0;
@@ -500,6 +504,12 @@
float mYScale;
float mXPrecision;
float mYPrecision;
+
+ bool mHaveVWheel;
+ bool mHaveHWheel;
+ float mVWheelScale;
+ float mHWheelScale;
+
sp<PointerControllerInterface> mPointerController;
struct LockedState {
@@ -985,123 +995,53 @@
virtual void process(const RawEvent* rawEvent);
private:
- struct RawAxes {
- RawAbsoluteAxisInfo x;
- RawAbsoluteAxisInfo y;
- RawAbsoluteAxisInfo hat0X;
- RawAbsoluteAxisInfo hat0Y;
- } mRawAxes;
+ struct Axis {
+ RawAbsoluteAxisInfo rawAxisInfo;
- struct NormalizedAxis {
- bool valid;
+ int32_t axis; // axis id
+ bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
- static const float min = -1.0f;
- static const float max = -1.0f;
+ float scale; // scale factor from raw to normalized values
+ float offset; // offset to add after scaling for normalization
- float scale; // scale factor
- float center; // center offset after scaling
- float precision; // precision
- float flat; // size of flat region
- float fuzz; // error tolerance
+ float min; // normalized inclusive minimum
+ float max; // normalized inclusive maximum
+ float flat; // normalized flat region size
+ float fuzz; // normalized error tolerance
- float value; // most recent value
+ float oldValue; // previous value
+ float newValue; // most recent value
- NormalizedAxis() : valid(false), scale(0), center(0), precision(0),
- flat(0), fuzz(0), value(0) {
- }
+ float filter; // filter out small variations of this size
- void configure(const RawAbsoluteAxisInfo& rawAxis) {
- if (rawAxis.valid && rawAxis.getRange() != 0) {
- valid = true;
- scale = 2.0f / rawAxis.getRange();
- precision = rawAxis.getRange();
- flat = rawAxis.flat * scale;
- fuzz = rawAxis.fuzz * scale;
- center = float(rawAxis.minValue + rawAxis.maxValue) / rawAxis.getRange();
- }
- }
-
- void resetState() {
- value = 0;
- }
-
- bool updateValue(int32_t rawValue) {
- float newValue = rawValue * scale - center;
- if (value == newValue) {
- return false;
- }
- value = newValue;
- return true;
+ void initialize(const RawAbsoluteAxisInfo& rawAxisInfo,
+ int32_t axis, bool explicitlyMapped, float scale, float offset,
+ float min, float max, float flat, float fuzz) {
+ this->rawAxisInfo = rawAxisInfo;
+ this->axis = axis;
+ this->explicitlyMapped = explicitlyMapped;
+ this->scale = scale;
+ this->offset = offset;
+ this->min = min;
+ this->max = max;
+ this->flat = flat;
+ this->fuzz = fuzz;
+ this->filter = 0;
+ this->oldValue = 0;
+ this->newValue = 0;
}
};
- struct DirectionalAxis : NormalizedAxis {
- int32_t direction; // most recent direction vector: value is one of -1, 0, 1.
+ // Axes indexed by raw ABS_* axis index.
+ KeyedVector<int32_t, Axis> mAxes;
- int32_t lastKeyCode; // most recent key code produced
+ void sync(nsecs_t when, bool force);
- DirectionalAxis() : lastKeyCode(0) {
- }
+ bool haveAxis(int32_t axis);
+ void pruneAxes(bool ignoreExplicitlyMappedAxes);
+ bool haveAxesChangedSignificantly();
- void resetState() {
- NormalizedAxis::resetState();
- direction = 0;
- lastKeyCode = 0;
- }
-
- bool updateValueAndDirection(int32_t rawValue) {
- if (!updateValue(rawValue)) {
- return false;
- }
- if (value > flat) {
- direction = 1;
- } else if (value < -flat) {
- direction = -1;
- } else {
- direction = 0;
- }
- return true;
- }
- };
-
- struct Axes {
- NormalizedAxis x;
- NormalizedAxis y;
- DirectionalAxis hat0X;
- DirectionalAxis hat0Y;
- } mAxes;
-
- struct Accumulator {
- enum {
- FIELD_ABS_X = 1,
- FIELD_ABS_Y = 2,
- FIELD_ABS_HAT0X = 4,
- FIELD_ABS_HAT0Y = 8,
-
- FIELD_ALL = FIELD_ABS_X | FIELD_ABS_Y | FIELD_ABS_HAT0X | FIELD_ABS_HAT0Y,
- };
-
- uint32_t fields;
-
- int32_t absX;
- int32_t absY;
- int32_t absHat0X;
- int32_t absHat0Y;
-
- inline void clear() {
- fields = 0;
- }
- } mAccumulator;
-
- void initialize();
-
- void sync(nsecs_t when);
-
- void notifyDirectionalAxis(DirectionalAxis& axis,
- nsecs_t when, int32_t metaState, int32_t lowKeyCode, int32_t highKeyCode);
-
- static void dumpNormalizedAxis(String8& dump,
- const NormalizedAxis& axis, const char* name);
+ static bool isCenteredAxis(int32_t axis);
};
} // namespace android
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 8ec1fd4..fac71bb 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -561,7 +561,11 @@
return -1;
}
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
+ return false;
+ }
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const {
Device* device = getDevice(deviceId);
if (device) {
@@ -579,6 +583,11 @@
return NAME_NOT_FOUND;
}
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const {
+ return NAME_NOT_FOUND;
+ }
+
virtual void addExcludedDevice(const char* deviceName) {
mExcludedDevices.add(String8(deviceName));
}
@@ -1473,15 +1482,15 @@
float x, float y, float pressure, float size,
float touchMajor, float touchMinor, float toolMajor, float toolMinor,
float orientation) {
- ASSERT_NEAR(x, coords.x, 1);
- ASSERT_NEAR(y, coords.y, 1);
- ASSERT_NEAR(pressure, coords.pressure, EPSILON);
- ASSERT_NEAR(size, coords.size, EPSILON);
- ASSERT_NEAR(touchMajor, coords.touchMajor, 1);
- ASSERT_NEAR(touchMinor, coords.touchMinor, 1);
- ASSERT_NEAR(toolMajor, coords.toolMajor, 1);
- ASSERT_NEAR(toolMinor, coords.toolMinor, 1);
- ASSERT_NEAR(orientation, coords.orientation, EPSILON);
+ ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+ ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
+ ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
+ ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1);
+ ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1);
+ ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
+ ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
+ ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
}
};
@@ -2078,7 +2087,6 @@
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
- ASSERT_NEAR(0.0f, args.pointerCoords[0].x, EPSILON);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
@@ -2893,8 +2901,8 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(50, args.pointerCoords[0].x, 1);
- ASSERT_NEAR(75, args.pointerCoords[0].y, 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2915,8 +2923,8 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(50, args.pointerCoords[0].x, 1);
- ASSERT_NEAR(75, args.pointerCoords[0].y, 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2928,8 +2936,8 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(75, args.pointerCoords[0].x, 1);
- ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].y, 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2941,8 +2949,8 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].x, 1);
- ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].y, 1);
+ ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2954,8 +2962,8 @@
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].x, 1);
- ASSERT_NEAR(50, args.pointerCoords[0].y, 1);
+ ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index b2d534b..df2cd1b 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -79,9 +79,9 @@
* Implementation of the device policy APIs.
*/
public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
- private static final int REQUEST_EXPIRE_PASSWORD = 5571;
+ private static final String TAG = "DevicePolicyManagerService";
- static final String TAG = "DevicePolicyManagerService";
+ private static final int REQUEST_EXPIRE_PASSWORD = 5571;
private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * 86400 * 1000; // 5 days, in ms
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index ba0f31b..44b8590 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -26,7 +26,7 @@
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
-import com.android.server.StatusBarManagerService;
+import com.android.server.EventLogTags;
import org.xmlpull.v1.XmlPullParserException;
@@ -1949,7 +1949,7 @@
private boolean canAddToLastInputMethod(InputMethodSubtype subtype) {
if (subtype == null) return true;
- return subtype.containsExtraValueKey(SUBTYPE_EXTRAVALUE_EXCLUDE_FROM_LAST_IME);
+ return !subtype.containsExtraValueKey(SUBTYPE_EXTRAVALUE_EXCLUDE_FROM_LAST_IME);
}
private void saveCurrentInputMethodAndSubtypeToHistory() {
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index ef3e89a..eaf68b0 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -610,11 +610,10 @@
* argv7 - Preamble
* argv8 - Max SCB
*/
- String str = String.format("softap set " + wlanIface + " " + softapIface +
- " %s %s %s", convertQuotedString(wifiConfig.SSID),
- wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
- "wpa2-psk" : "open",
- convertQuotedString(wifiConfig.preSharedKey));
+ String str = String.format("softap set " + wlanIface + " " + softapIface +
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
+ getSecurityType(wifiConfig),
+ convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
mConnector.doCommand(String.format("softap startap"));
@@ -631,6 +630,17 @@
return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"';
}
+ private String getSecurityType(WifiConfiguration wifiConfig) {
+ switch (wifiConfig.getAuthType()) {
+ case KeyMgmt.WPA_PSK:
+ return "wpa-psk";
+ case KeyMgmt.WPA2_PSK:
+ return "wpa2-psk";
+ default:
+ return "open";
+ }
+ }
+
public void stopAccessPoint() throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
@@ -656,7 +666,7 @@
} else {
String str = String.format("softap set " + wlanIface + " " + softapIface
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
- wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? "wpa2-psk" : "open",
+ getSecurityType(wifiConfig),
convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index caf6376..d80a2cd 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -40,7 +40,6 @@
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Binder;
-import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -50,7 +49,6 @@
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Settings.SettingNotFoundException;
@@ -69,14 +67,13 @@
import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
-class PowerManagerService extends IPowerManager.Stub
+public class PowerManagerService extends IPowerManager.Stub
implements LocalPowerManager, Watchdog.Monitor {
private static final String TAG = "PowerManagerService";
@@ -2689,7 +2686,7 @@
}
}
- void setPolicy(WindowManagerPolicy p) {
+ public void setPolicy(WindowManagerPolicy p) {
synchronized (mLocks) {
mPolicy = p;
mLocks.notifyAll();
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 5ada77b..8df8177 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -39,6 +39,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
+import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index a1f43b4..80b0174 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -16,6 +16,7 @@
package com.android.server;
+
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupAgentHelper;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6a6cc2a..52c47e1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -17,6 +17,7 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
+import com.android.server.wm.WindowManagerService;
import com.android.internal.app.ShutdownThread;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index 460fd4d..1bc203e 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.hardware.IUsbManager;
+import android.hardware.UsbAccessory;
import android.hardware.UsbConstants;
import android.hardware.UsbDevice;
import android.hardware.UsbEndpoint;
@@ -43,7 +44,11 @@
import java.util.HashMap;
/**
- * <p>UsbService monitors for changes to USB state.
+ * UsbService monitors for changes to USB state.
+ * This includes code for both USB host support (where the android device is the host)
+ * as well as USB device support (android device is connected to a USB host).
+ * Accessory mode is a special case of USB device mode, where the android device is
+ * connected to a USB host that supports the android accessory protocol.
*/
class UsbService extends IUsbManager.Stub {
private static final String TAG = UsbService.class.getSimpleName();
@@ -62,7 +67,9 @@
private static final String USB_COMPOSITE_CLASS_PATH =
"/sys/class/usb_composite";
- private static final int MSG_UPDATE = 0;
+ private static final int MSG_UPDATE_STATE = 0;
+ private static final int MSG_FUNCTION_ENABLED = 1;
+ private static final int MSG_FUNCTION_DISABLED = 2;
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
@@ -81,6 +88,7 @@
private final ArrayList<String> mEnabledFunctions = new ArrayList<String>();
private final ArrayList<String> mDisabledFunctions = new ArrayList<String>();
+ // contains all connected USB devices (for USB host mode)
private final HashMap<String,UsbDevice> mDevices = new HashMap<String,UsbDevice>();
// USB busses to exclude from USB host support
@@ -88,8 +96,76 @@
private boolean mSystemReady;
- private final Context mContext;
+ private UsbAccessory mCurrentAccessory;
+ // functions to restore after exiting accessory mode
+ private final ArrayList<String> mAccessoryRestoreFunctions = new ArrayList<String>();
+ private final Context mContext;
+ private final Object mLock = new Object();
+
+ /*
+ * Handles USB function enable/disable events (device mode)
+ */
+ private final void functionEnabledLocked(String function, boolean enabled) {
+ boolean enteringAccessoryMode =
+ (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function));
+
+ if (enteringAccessoryMode) {
+ // keep a list of functions to reenable after exiting accessory mode
+ mAccessoryRestoreFunctions.clear();
+ int count = mEnabledFunctions.size();
+ for (int i = 0; i < count; i++) {
+ String f = mEnabledFunctions.get(i);
+ // RNDIS should not be restored and adb is handled automatically
+ if (!UsbManager.USB_FUNCTION_RNDIS.equals(f) &&
+ !UsbManager.USB_FUNCTION_ADB.equals(f) &&
+ !UsbManager.USB_FUNCTION_ACCESSORY.equals(f)) {
+ mAccessoryRestoreFunctions.add(f);
+ }
+ }
+ }
+ if (enabled) {
+ if (!mEnabledFunctions.contains(function)) {
+ mEnabledFunctions.add(function);
+ }
+ mDisabledFunctions.remove(function);
+ } else {
+ if (!mDisabledFunctions.contains(function)) {
+ mDisabledFunctions.add(function);
+ }
+ mEnabledFunctions.remove(function);
+ }
+
+ if (enteringAccessoryMode) {
+ String[] strings = nativeGetAccessoryStrings();
+ if (strings != null) {
+ Log.d(TAG, "entering USB accessory mode");
+ mCurrentAccessory = new UsbAccessory(strings);
+ Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
+ // add strings as separate extras to allow filtering
+ if (strings[0] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_MANUFACTURER, strings[0]);
+ }
+ if (strings[1] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_PRODUCT, strings[1]);
+ }
+ if (strings[2] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_TYPE, strings[2]);
+ }
+ if (strings[3] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_VERSION, strings[3]);
+ }
+ mContext.sendBroadcast(intent);
+ } else {
+ Log.e(TAG, "nativeGetAccessoryStrings failed");
+ }
+ }
+ }
+
+ /*
+ * Listens for uevent messages from the kernel to monitor the USB state (device mode)
+ */
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -97,7 +173,7 @@
Slog.v(TAG, "USB UEVENT: " + event.toString());
}
- synchronized (this) {
+ synchronized (mLock) {
String name = event.get("SWITCH_NAME");
String state = event.get("SWITCH_STATE");
if (name != null && state != null) {
@@ -126,18 +202,11 @@
if (function != null && enabledStr != null) {
// Note: we do not broadcast a change when a function is enabled or disabled.
// We just record the state change for the next broadcast.
- boolean enabled = "1".equals(enabledStr);
- if (enabled) {
- if (!mEnabledFunctions.contains(function)) {
- mEnabledFunctions.add(function);
- }
- mDisabledFunctions.remove(function);
- } else {
- if (!mDisabledFunctions.contains(function)) {
- mDisabledFunctions.add(function);
- }
- mEnabledFunctions.remove(function);
- }
+ int what = ("1".equals(enabledStr) ?
+ MSG_FUNCTION_ENABLED : MSG_FUNCTION_DISABLED);
+ Message msg = Message.obtain(mHandler, what);
+ msg.obj = function;
+ mHandler.sendMessage(msg);
}
}
}
@@ -161,6 +230,7 @@
private final void init() {
char[] buffer = new char[1024];
+ // Read initial USB state (device mode)
mConfiguration = -1;
try {
FileReader file = new FileReader(USB_CONNECTED_PATH);
@@ -181,6 +251,7 @@
if (mConfiguration < 0)
return;
+ // Read initial list of enabled and disabled functions (device mode)
try {
File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
for (int i = 0; i < files.length; i++) {
@@ -213,6 +284,7 @@
return false;
}
+ /* returns true if the USB device should not be accessible by applications (host mode) */
private boolean isBlackListed(int clazz, int subClass, int protocol) {
// blacklist hubs
if (clazz == UsbConstants.USB_CLASS_HUB) return true;
@@ -226,7 +298,7 @@
return false;
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus() to report new USB devices (host mode) */
private void usbDeviceAdded(String deviceName, int vendorID, int productID,
int deviceClass, int deviceSubclass, int deviceProtocol,
/* array of quintuples containing id, class, subclass, protocol
@@ -241,7 +313,7 @@
return;
}
- synchronized (mDevices) {
+ synchronized (mLock) {
if (mDevices.get(deviceName) != null) {
Log.w(TAG, "device already on mDevices list: " + deviceName);
return;
@@ -300,9 +372,9 @@
}
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus to report USB device removal (host mode) */
private void usbDeviceRemoved(String deviceName) {
- synchronized (mDevices) {
+ synchronized (mLock) {
UsbDevice device = mDevices.remove(deviceName);
if (device != null) {
Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
@@ -325,7 +397,7 @@
}
void systemReady() {
- synchronized (this) {
+ synchronized (mLock) {
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_hasUsbHostSupport)) {
// start monitoring for connected USB devices
@@ -337,21 +409,27 @@
}
}
+ /*
+ * Sends a message to update the USB connected and configured state (device mode).
+ * If delayed is true, then we add a small delay in sending the message to debounce
+ * the USB connection when enabling USB tethering.
+ */
private final void update(boolean delayed) {
- mHandler.removeMessages(MSG_UPDATE);
- mHandler.sendEmptyMessageDelayed(MSG_UPDATE, delayed ? UPDATE_DELAY : 0);
+ mHandler.removeMessages(MSG_UPDATE_STATE);
+ mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATE, delayed ? UPDATE_DELAY : 0);
}
- /* Returns a list of all currently attached USB devices */
+ /* Returns a list of all currently attached USB devices (host mdoe) */
public void getDeviceList(Bundle devices) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
- synchronized (mDevices) {
+ synchronized (mLock) {
for (String name : mDevices.keySet()) {
devices.putParcelable(name, mDevices.get(name));
}
}
}
+ /* Opens the specified USB device (host mode) */
public ParcelFileDescriptor openDevice(String deviceName) {
if (isBlackListed(deviceName)) {
throw new SecurityException("USB device is on a restricted bus");
@@ -359,13 +437,29 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
if (mDevices.get(deviceName) == null) {
// if it is not in mDevices, it either does not exist or is blacklisted
- throw new IllegalArgumentException("device " + deviceName + " does not exist or is restricted");
+ throw new IllegalArgumentException(
+ "device " + deviceName + " does not exist or is restricted");
}
return nativeOpenDevice(deviceName);
}
+ /* returns the currently attached USB accessory (device mode) */
+ public UsbAccessory getCurrentAccessory() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
+ return mCurrentAccessory;
+ }
+
+ /* opens the currently attached USB accessory (device mode) */
+ public ParcelFileDescriptor openAccessory() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
+ return nativeOpenAccessory();
+ }
+
+ /*
+ * This handler is for deferred handling of events related to device mode and accessories.
+ */
private final Handler mHandler = new Handler() {
- private void addEnabledFunctions(Intent intent) {
+ private void addEnabledFunctionsLocked(Intent intent) {
// include state of all USB functions in our extras
for (int i = 0; i < mEnabledFunctions.size(); i++) {
intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
@@ -377,10 +471,38 @@
@Override
public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE:
- synchronized (this) {
+ synchronized (mLock) {
+ switch (msg.what) {
+ case MSG_UPDATE_STATE:
if (mConnected != mLastConnected || mConfiguration != mLastConfiguration) {
+ if (mConnected == 0 && mCurrentAccessory != null) {
+ // turn off accessory mode when we are disconnected
+ if (UsbManager.setFunctionEnabled(
+ UsbManager.USB_FUNCTION_ACCESSORY, false)) {
+ Log.d(TAG, "exited USB accessory mode");
+
+ // restore previously enabled functions
+ for (String function : mAccessoryRestoreFunctions) {
+ if (UsbManager.setFunctionEnabled(function, true)) {
+ Log.e(TAG, "could not reenable function " + function);
+ }
+ }
+ mAccessoryRestoreFunctions.clear();
+
+ Intent intent = new Intent(
+ UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
+ mContext.sendBroadcast(intent);
+ mCurrentAccessory = null;
+
+ // this will cause an immediate reset of the USB bus,
+ // so there is no point in sending the
+ // function disabled broadcast.
+ return;
+ } else {
+ Log.e(TAG, "could not disable USB_FUNCTION_ACCESSORY");
+ }
+ }
final ContentResolver cr = mContext.getContentResolver();
if (Settings.Secure.getInt(cr,
@@ -397,15 +519,23 @@
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected != 0);
intent.putExtra(UsbManager.USB_CONFIGURATION, mConfiguration);
- addEnabledFunctions(intent);
+ addEnabledFunctionsLocked(intent);
mContext.sendStickyBroadcast(intent);
}
- }
- break;
+ break;
+ case MSG_FUNCTION_ENABLED:
+ case MSG_FUNCTION_DISABLED:
+ functionEnabledLocked((String)msg.obj, msg.what == MSG_FUNCTION_ENABLED);
+ break;
+ }
}
}
};
+ // host support
private native void monitorUsbHostBus();
private native ParcelFileDescriptor nativeOpenDevice(String deviceName);
+ // accessory support
+ private native String[] nativeGetAccessoryStrings();
+ private native ParcelFileDescriptor nativeOpenAccessory();
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 997e750..b1a6a9a 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -70,8 +70,6 @@
import com.android.internal.service.wallpaper.ImageWallpaper;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
-import com.android.server.DevicePolicyManagerService.ActiveAdmin;
-import com.android.server.DevicePolicyManagerService.MyPackageMonitor;
class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5e78353..cc25e8d 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -42,14 +42,18 @@
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
+import android.net.NetworkInfo.DetailedState;
+import android.net.TrafficStats;
import android.os.Binder;
import android.os.Handler;
+import android.os.Messenger;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
@@ -111,6 +115,20 @@
private final IBatteryStats mBatteryStats;
+ private boolean mEnableTrafficStatsPoll = false;
+ private int mTrafficStatsPollToken = 0;
+ private long mTxPkts;
+ private long mRxPkts;
+ /* Tracks last reported data activity */
+ private int mDataActivity;
+ private String mInterfaceName;
+
+ /**
+ * Interval in milliseconds between polling for traffic
+ * statistics
+ */
+ private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000;
+
/**
* See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a
* Settings.Secure value is not present. This timeout value is chosen as
@@ -123,6 +141,9 @@
private static final String ACTION_DEVICE_IDLE =
"com.android.server.WifiManager.action.DEVICE_IDLE";
+ private static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 1;
+ private static final int CMD_TRAFFIC_STATS_POLL = 2;
+
private boolean mIsReceiverRegistered = false;
@@ -180,18 +201,20 @@
/**
* Asynchronous channel to WifiStateMachine
*/
- private AsyncChannel mChannel;
+ private AsyncChannel mWifiStateMachineChannel;
/**
- * TODO: Possibly change WifiService into an AsyncService.
+ * Clients receiving asynchronous messages
*/
- private class WifiServiceHandler extends Handler {
- private AsyncChannel mWshChannel;
+ private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>();
- WifiServiceHandler(android.os.Looper looper, Context context) {
+ /**
+ * Handles client connections
+ */
+ private class AsyncServiceHandler extends Handler {
+
+ AsyncServiceHandler(android.os.Looper looper) {
super(looper);
- mWshChannel = new AsyncChannel();
- mWshChannel.connect(context, this, mWifiStateMachine.getHandler());
}
@Override
@@ -199,11 +222,33 @@
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- mChannel = mWshChannel;
+ Slog.d(TAG, "New client listening to asynchronous messages");
+ mClients.add((AsyncChannel) msg.obj);
} else {
- Slog.d(TAG, "WifiServicehandler.handleMessage could not connect error=" +
- msg.arg1);
- mChannel = null;
+ Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
+ }
+ break;
+ }
+ case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
+ AsyncChannel ac = new AsyncChannel();
+ ac.connect(mContext, this, msg.replyTo);
+ break;
+ }
+ case CMD_ENABLE_TRAFFIC_STATS_POLL: {
+ mEnableTrafficStatsPoll = (msg.arg1 == 1);
+ mTrafficStatsPollToken++;
+ if (mEnableTrafficStatsPoll) {
+ notifyOnDataActivity();
+ sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
+ }
+ break;
+ }
+ case CMD_TRAFFIC_STATS_POLL: {
+ if (msg.arg1 == mTrafficStatsPollToken) {
+ notifyOnDataActivity();
+ sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
}
break;
}
@@ -214,7 +259,40 @@
}
}
}
- WifiServiceHandler mHandler;
+ private AsyncServiceHandler mAsyncServiceHandler;
+
+ /**
+ * Handles interaction with WifiStateMachine
+ */
+ private class WifiStateMachineHandler extends Handler {
+ private AsyncChannel mWsmChannel;
+
+ WifiStateMachineHandler(android.os.Looper looper) {
+ super(looper);
+ mWsmChannel = new AsyncChannel();
+ mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ mWifiStateMachineChannel = mWsmChannel;
+ } else {
+ Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1);
+ mWifiStateMachineChannel = null;
+ }
+ break;
+ }
+ default: {
+ Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
+ break;
+ }
+ }
+ }
+ }
+ WifiStateMachineHandler mWifiStateMachineHandler;
/**
* Temporary for computing UIDS that are responsible for starting WIFI.
@@ -224,7 +302,10 @@
WifiService(Context context) {
mContext = context;
- mWifiStateMachine = new WifiStateMachine(mContext);
+
+ mInterfaceName = SystemProperties.get("wifi.interface", "wlan0");
+
+ mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);
mWifiStateMachine.enableRssiPolling(true);
mBatteryStats = BatteryStatsService.getService();
@@ -232,10 +313,6 @@
Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
- HandlerThread wifiThread = new HandlerThread("WifiService");
- wifiThread.start();
- mHandler = new WifiServiceHandler(wifiThread.getLooper(), context);
-
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
@@ -271,6 +348,7 @@
switch(mNetworkInfo.getDetailedState()) {
case CONNECTED:
case DISCONNECTED:
+ evaluateTrafficStatsPolling();
resetNotification();
break;
}
@@ -281,6 +359,11 @@
}
}, filter);
+ HandlerThread wifiThread = new HandlerThread("WifiService");
+ wifiThread.start();
+ mAsyncServiceHandler = new AsyncServiceHandler(wifiThread.getLooper());
+ mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
+
// Setting is in seconds
NOTIFICATION_REPEAT_DELAY_MS = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l;
@@ -337,10 +420,10 @@
*/
public boolean pingSupplicant() {
enforceAccessPermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncPingSupplicant(mChannel);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -501,15 +584,12 @@
public synchronized void setWifiApConfiguration(WifiConfiguration wifiConfig) {
enforceChangePermission();
final ContentResolver cr = mContext.getContentResolver();
- boolean isWpa;
if (wifiConfig == null)
return;
+ int authType = wifiConfig.getAuthType();
Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_SSID, wifiConfig.SSID);
- isWpa = wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK);
- Settings.Secure.putInt(cr,
- Settings.Secure.WIFI_AP_SECURITY,
- isWpa ? KeyMgmt.WPA_PSK : KeyMgmt.NONE);
- if (isWpa)
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_SECURITY, authType);
+ if (authType != KeyMgmt.NONE)
Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_PASSWD, wifiConfig.preSharedKey);
}
@@ -553,10 +633,10 @@
*/
public int addOrUpdateNetwork(WifiConfiguration config) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncAddOrUpdateNetwork(mChannel, config);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return -1;
}
}
@@ -569,10 +649,10 @@
*/
public boolean removeNetwork(int netId) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncRemoveNetwork(mChannel, netId);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -586,10 +666,11 @@
*/
public boolean enableNetwork(int netId, boolean disableOthers) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncEnableNetwork(mChannel, netId, disableOthers);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId,
+ disableOthers);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -602,10 +683,10 @@
*/
public boolean disableNetwork(int netId) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncDisableNetwork(mChannel, netId);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -642,10 +723,10 @@
public boolean saveConfiguration() {
boolean result = true;
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncSaveConfig(mChannel);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -779,14 +860,23 @@
public WpsResult startWps(WpsConfiguration config) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.startWps(mChannel, config);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.startWps(mWifiStateMachineChannel, config);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return new WpsResult(WpsResult.Status.FAILURE);
}
}
+ /**
+ * Get a reference to handler. This is used by a client to establish
+ * an AsyncChannel communication with WifiService
+ */
+ public Messenger getMessenger() {
+ enforceAccessPermission();
+ return new Messenger(mAsyncServiceHandler);
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -808,6 +898,7 @@
// Once the screen is on, we are not keeping WIFI running
// because of any locks so clear that tracking immediately.
reportStartWorkSource();
+ evaluateTrafficStatsPolling();
mWifiStateMachine.enableRssiPolling(true);
mWifiStateMachine.enableAllNetworks();
updateWifiState();
@@ -816,6 +907,7 @@
Slog.d(TAG, "ACTION_SCREEN_OFF");
}
mScreenOff = true;
+ evaluateTrafficStatsPolling();
mWifiStateMachine.enableRssiPolling(false);
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
@@ -1419,6 +1511,48 @@
}
}
+ /**
+ * Evaluate if traffic stats polling is needed based on
+ * connection and screen on status
+ */
+ private void evaluateTrafficStatsPolling() {
+ Message msg;
+ if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) {
+ msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0);
+ } else {
+ msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0);
+ }
+ msg.sendToTarget();
+ }
+
+ private void notifyOnDataActivity() {
+ long sent, received;
+ long preTxPkts = mTxPkts, preRxPkts = mRxPkts;
+ int dataActivity = WifiManager.DATA_ACTIVITY_NONE;
+
+ mTxPkts = TrafficStats.getTxPackets(mInterfaceName);
+ mRxPkts = TrafficStats.getRxPackets(mInterfaceName);
+
+ if (preTxPkts > 0 || preRxPkts > 0) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
+ if (sent > 0) {
+ dataActivity |= WifiManager.DATA_ACTIVITY_OUT;
+ }
+ if (received > 0) {
+ dataActivity |= WifiManager.DATA_ACTIVITY_IN;
+ }
+
+ if (dataActivity != mDataActivity && !mScreenOff) {
+ mDataActivity = dataActivity;
+ for (AsyncChannel client : mClients) {
+ client.sendMessage(WifiManager.DATA_ACTIVITY_NOTIFICATION, mDataActivity);
+ }
+ }
+ }
+ }
+
+
private void checkAndSetNotification() {
// If we shouldn't place a notification on available networks, then
// don't bother doing any of the following
diff --git a/services/java/com/android/server/WifiWatchdogService.java b/services/java/com/android/server/WifiWatchdogService.java
index 46d6bef..94531bb 100644
--- a/services/java/com/android/server/WifiWatchdogService.java
+++ b/services/java/com/android/server/WifiWatchdogService.java
@@ -22,8 +22,9 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
import android.net.NetworkInfo;
-import android.net.DhcpInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -42,6 +43,7 @@
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
+import java.util.Collection;
import java.util.List;
import java.util.Random;
@@ -77,7 +79,8 @@
private Context mContext;
private ContentResolver mContentResolver;
private WifiManager mWifiManager;
-
+ private ConnectivityManager mConnectivityManager;
+
/**
* The main watchdog thread.
*/
@@ -310,19 +313,26 @@
}
/**
- * Gets the DNS of the current AP.
+ * Gets the first DNS of the current AP.
*
- * @return The DNS of the current AP.
+ * @return The first DNS of the current AP.
*/
- private int getDns() {
- DhcpInfo addressInfo = mWifiManager.getDhcpInfo();
- if (addressInfo != null) {
- return addressInfo.dns1;
- } else {
- return -1;
+ private InetAddress getDns() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = (ConnectivityManager)mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
}
+
+ LinkProperties linkProperties = mConnectivityManager.getLinkProperties(
+ ConnectivityManager.TYPE_WIFI);
+ if (linkProperties == null) return null;
+
+ Collection<InetAddress> dnses = linkProperties.getDnses();
+ if (dnses == null || dnses.size() == 0) return null;
+
+ return dnses.iterator().next();
}
-
+
/**
* Checks whether the DNS can be reached using multiple attempts according
* to the current setting values.
@@ -330,29 +340,28 @@
* @return Whether the DNS is reachable
*/
private boolean checkDnsConnectivity() {
- int dns = getDns();
- if (dns == -1) {
+ InetAddress dns = getDns();
+ if (dns == null) {
if (V) {
myLogV("checkDnsConnectivity: Invalid DNS, returning false");
}
return false;
}
-
+
if (V) {
- myLogV("checkDnsConnectivity: Checking 0x" +
- Integer.toHexString(Integer.reverseBytes(dns)) + " for connectivity");
+ myLogV("checkDnsConnectivity: Checking " + dns.getHostAddress() + " for connectivity");
}
int numInitialIgnoredPings = getInitialIgnoredPingCount();
int numPings = getPingCount();
int pingDelay = getPingDelayMs();
int acceptableLoss = getAcceptablePacketLossPercentage();
-
+
/** See {@link Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} */
int ignoredPingCounter = 0;
int pingCounter = 0;
int successCounter = 0;
-
+
// No connectivity check needed
if (numPings == 0) {
return true;
@@ -371,20 +380,20 @@
pingCounter++;
successCounter++;
}
-
+
if (V) {
Slog.v(TAG, (dnsAlive ? " +" : " Ignored: -"));
}
if (shouldCancel()) return false;
-
+
try {
Thread.sleep(pingDelay);
} catch (InterruptedException e) {
Slog.w(TAG, "Interrupted while pausing between pings", e);
}
}
-
+
// Do the pings that we use to measure packet loss
for (; pingCounter < numPings; pingCounter++) {
if (shouldCancel()) return false;
@@ -401,40 +410,41 @@
}
if (shouldCancel()) return false;
-
+
try {
Thread.sleep(pingDelay);
} catch (InterruptedException e) {
Slog.w(TAG, "Interrupted while pausing between pings", e);
}
}
-
+
int packetLossPercentage = 100 * (numPings - successCounter) / numPings;
if (D) {
Slog.d(TAG, packetLossPercentage
+ "% packet loss (acceptable is " + acceptableLoss + "%)");
}
-
+
return !shouldCancel() && (packetLossPercentage <= acceptableLoss);
}
private boolean backgroundCheckDnsConnectivity() {
- int dns = getDns();
- if (false && V) {
- myLogV("backgroundCheckDnsConnectivity: Background checking " + dns +
- " for connectivity");
- }
-
- if (dns == -1) {
+ InetAddress dns = getDns();
+
+ if (dns == null) {
if (V) {
myLogV("backgroundCheckDnsConnectivity: DNS is empty, returning false");
}
return false;
}
-
+
+ if (false && V) {
+ myLogV("backgroundCheckDnsConnectivity: Background checking " +
+ dns.getHostAddress() + " for connectivity");
+ }
+
return DnsPinger.isDnsReachable(dns, getBackgroundCheckTimeoutMs());
}
-
+
/**
* Signals the current action to cancel.
*/
@@ -1207,43 +1217,37 @@
/** Used to generate IDs */
private static Random sRandom = new Random();
-
- static boolean isDnsReachable(int dns, int timeout) {
+
+ static boolean isDnsReachable(InetAddress dnsAddress, int timeout) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
-
+
// Set some socket properties
socket.setSoTimeout(timeout);
-
+
byte[] buf = new byte[DNS_QUERY_BASE_SIZE];
fillQuery(buf);
-
- // Send the DNS query
- byte parts[] = new byte[4];
- parts[0] = (byte)(dns & 0xff);
- parts[1] = (byte)((dns >> 8) & 0xff);
- parts[2] = (byte)((dns >> 16) & 0xff);
- parts[3] = (byte)((dns >> 24) & 0xff);
- InetAddress dnsAddress = InetAddress.getByAddress(parts);
+ // Send the DNS query
+
DatagramPacket packet = new DatagramPacket(buf,
buf.length, dnsAddress, DNS_PORT);
socket.send(packet);
-
+
// Wait for reply (blocks for the above timeout)
DatagramPacket replyPacket = new DatagramPacket(buf, buf.length);
socket.receive(replyPacket);
// If a timeout occurred, an exception would have been thrown. We got a reply!
return true;
-
+
} catch (SocketException e) {
if (V) {
Slog.v(TAG, "DnsPinger.isReachable received SocketException", e);
}
return false;
-
+
} catch (UnknownHostException e) {
if (V) {
Slog.v(TAG, "DnsPinger.isReachable is unable to resolve the DNS host", e);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9e3b9c6..399c19a 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -24,8 +24,8 @@
import com.android.server.ProcessStats;
import com.android.server.SystemServer;
import com.android.server.Watchdog;
-import com.android.server.WindowManagerService;
import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.WindowManagerService;
import dalvik.system.Zygote;
@@ -4969,11 +4969,6 @@
enforceCallingPermission(android.Manifest.permission.GET_TASKS,
"getRecentTasks()");
- final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
- && checkCallingPermission(
- android.Manifest.permission.READ_FRAME_BUFFER)
- == PackageManager.PERMISSION_GRANTED;
-
IPackageManager pm = AppGlobals.getPackageManager();
ActivityRecord resumed = mMainStack.mResumedActivity;
@@ -4991,17 +4986,10 @@
ActivityManager.RecentTaskInfo rti
= new ActivityManager.RecentTaskInfo();
rti.id = tr.numActivities > 0 ? tr.taskId : -1;
+ rti.persistentId = tr.taskId;
rti.baseIntent = new Intent(
tr.intent != null ? tr.intent : tr.affinityIntent);
rti.origActivity = tr.origActivity;
-
- if (canReadFb) {
- if (resumed != null && resumed.task == tr) {
- rti.thumbnail = resumed.stack.screenshotActivities(resumed);
- } else {
- rti.thumbnail = tr.lastThumbnail;
- }
- }
rti.description = tr.lastDescription;
if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
@@ -5030,6 +5018,26 @@
}
}
+ public Bitmap getTaskThumbnail(int id) {
+ synchronized (this) {
+ enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
+ "getTaskThumbnail()");
+ ActivityRecord resumed = mMainStack.mResumedActivity;
+ final int N = mRecentTasks.size();
+ for (int i=0; i<N; i++) {
+ TaskRecord tr = mRecentTasks.get(i);
+ if (tr.taskId == id) {
+ if (resumed != null && resumed.task == tr) {
+ return resumed.stack.screenshotActivities(resumed);
+ } else {
+ return tr.lastThumbnail;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
int j;
TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
@@ -5085,6 +5093,9 @@
for (int i=0; i<N; i++) {
TaskRecord tr = mRecentTasks.get(i);
if (tr.taskId == task) {
+ if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+ mMainStack.mUserLeaving = true;
+ }
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
@@ -5097,6 +5108,9 @@
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
if (hr.task.taskId == task) {
+ if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+ mMainStack.mUserLeaving = true;
+ }
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
new file mode 100644
index 0000000..d3d9df4
--- /dev/null
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.pm.ActivityInfo;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.IApplicationToken;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Version of WindowToken that is specifically for a particular application (or
+ * really activity) that is displaying windows.
+ */
+class AppWindowToken extends WindowToken {
+ // Non-null only for application tokens.
+ final IApplicationToken appToken;
+
+ // All of the windows and child windows that are included in this
+ // application token. Note this list is NOT sorted!
+ final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
+
+ int groupId = -1;
+ boolean appFullscreen;
+ int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+ // The input dispatching timeout for this application token in nanoseconds.
+ long inputDispatchingTimeoutNanos;
+
+ // These are used for determining when all windows associated with
+ // an activity have been drawn, so they can be made visible together
+ // at the same time.
+ int lastTransactionSequence;
+ int numInterestingWindows;
+ int numDrawnWindows;
+ boolean inPendingTransaction;
+ boolean allDrawn;
+
+ // Is this token going to be hidden in a little while? If so, it
+ // won't be taken into account for setting the screen orientation.
+ boolean willBeHidden;
+
+ // Is this window's surface needed? This is almost like hidden, except
+ // it will sometimes be true a little earlier: when the token has
+ // been shown, but is still waiting for its app transition to execute
+ // before making its windows shown.
+ boolean hiddenRequested;
+
+ // Have we told the window clients to hide themselves?
+ boolean clientHidden;
+
+ // Last visibility state we reported to the app token.
+ boolean reportedVisible;
+
+ // Set to true when the token has been removed from the window mgr.
+ boolean removed;
+
+ // Have we been asked to have this token keep the screen frozen?
+ boolean freezingScreen;
+
+ boolean animating;
+ Animation animation;
+ boolean hasTransformation;
+ final Transformation transformation = new Transformation();
+
+ // Offset to the window of all layers in the token, for use by
+ // AppWindowToken animations.
+ int animLayerAdjustment;
+
+ // Information about an application starting window if displayed.
+ StartingData startingData;
+ WindowState startingWindow;
+ View startingView;
+ boolean startingDisplayed;
+ boolean startingMoved;
+ boolean firstWindowDrawn;
+
+ // Input application handle used by the input dispatcher.
+ InputApplicationHandle mInputApplicationHandle;
+
+ AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
+ super(_service, _token.asBinder(),
+ WindowManager.LayoutParams.TYPE_APPLICATION, true);
+ appWindowToken = this;
+ appToken = _token;
+ mInputApplicationHandle = new InputApplicationHandle(this);
+ lastTransactionSequence = service.mTransactionSequence-1;
+ }
+
+ public void setAnimation(Animation anim) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+ animation = anim;
+ animating = false;
+ anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(service.mTransitionAnimationScale);
+ int zorder = anim.getZAdjustment();
+ int adj = 0;
+ if (zorder == Animation.ZORDER_TOP) {
+ adj = WindowManagerService.TYPE_LAYER_OFFSET;
+ } else if (zorder == Animation.ZORDER_BOTTOM) {
+ adj = -WindowManagerService.TYPE_LAYER_OFFSET;
+ }
+
+ if (animLayerAdjustment != adj) {
+ animLayerAdjustment = adj;
+ updateLayers();
+ }
+ }
+
+ public void setDummyAnimation() {
+ if (animation == null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting dummy animation in " + this);
+ animation = WindowManagerService.sDummyAnimation;
+ }
+ }
+
+ public void clearAnimation() {
+ if (animation != null) {
+ animation = null;
+ animating = true;
+ }
+ }
+
+ void updateLayers() {
+ final int N = allAppWindows.size();
+ final int adj = animLayerAdjustment;
+ for (int i=0; i<N; i++) {
+ WindowState w = allAppWindows.get(i);
+ w.mAnimLayer = w.mLayer + adj;
+ if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Updating layer " + w + ": "
+ + w.mAnimLayer);
+ if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) {
+ service.setInputMethodAnimLayerAdjustment(adj);
+ }
+ if (w == service.mWallpaperTarget && service.mLowerWallpaperTarget == null) {
+ service.setWallpaperAnimLayerAdjustmentLocked(adj);
+ }
+ }
+ }
+
+ void sendAppVisibilityToClients() {
+ final int N = allAppWindows.size();
+ for (int i=0; i<N; i++) {
+ WindowState win = allAppWindows.get(i);
+ if (win == startingWindow && clientHidden) {
+ // Don't hide the starting window.
+ continue;
+ }
+ try {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+ "Setting visibility of " + win + ": " + (!clientHidden));
+ win.mClient.dispatchAppVisibility(!clientHidden);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ void showAllWindowsLocked() {
+ final int NW = allAppWindows.size();
+ for (int i=0; i<NW; i++) {
+ WindowState w = allAppWindows.get(i);
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+ "performing show on: " + w);
+ w.performShowLocked();
+ }
+ }
+
+ // This must be called while inside a transaction.
+ boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+ if (!service.mDisplayFrozen && service.mPolicy.isScreenOn()) {
+ // We will run animations as long as the display isn't frozen.
+
+ if (animation == WindowManagerService.sDummyAnimation) {
+ // This guy is going to animate, but not yet. For now count
+ // it as not animating for purposes of scheduling transactions;
+ // when it is really time to animate, this will be set to
+ // a real animation and the next call will execute normally.
+ return false;
+ }
+
+ if ((allDrawn || animating || startingDisplayed) && animation != null) {
+ if (!animating) {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Starting animation in " + this +
+ " @ " + currentTime + ": dw=" + dw + " dh=" + dh
+ + " scale=" + service.mTransitionAnimationScale
+ + " allDrawn=" + allDrawn + " animating=" + animating);
+ animation.initialize(dw, dh, dw, dh);
+ animation.setStartTime(currentTime);
+ animating = true;
+ }
+ transformation.clear();
+ final boolean more = animation.getTransformation(
+ currentTime, transformation);
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Stepped animation in " + this +
+ ": more=" + more + ", xform=" + transformation);
+ if (more) {
+ // we're done!
+ hasTransformation = true;
+ return true;
+ }
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Finished animation in " + this +
+ " @ " + currentTime);
+ animation = null;
+ }
+ } else if (animation != null) {
+ // If the display is frozen, and there is a pending animation,
+ // clear it and make sure we run the cleanup code.
+ animating = true;
+ animation = null;
+ }
+
+ hasTransformation = false;
+
+ if (!animating) {
+ return false;
+ }
+
+ clearAnimation();
+ animating = false;
+ if (animLayerAdjustment != 0) {
+ animLayerAdjustment = 0;
+ updateLayers();
+ }
+ if (service.mInputMethodTarget != null && service.mInputMethodTarget.mAppToken == this) {
+ service.moveInputMethodWindowsIfNeededLocked(true);
+ }
+
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Animation done in " + this
+ + ": reportedVisible=" + reportedVisible);
+
+ transformation.clear();
+
+ final int N = windows.size();
+ for (int i=0; i<N; i++) {
+ windows.get(i).finishExit();
+ }
+ updateReportedVisibilityLocked();
+
+ return false;
+ }
+
+ void updateReportedVisibilityLocked() {
+ if (appToken == null) {
+ return;
+ }
+
+ int numInteresting = 0;
+ int numVisible = 0;
+ boolean nowGone = true;
+
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Update reported visibility: " + this);
+ final int N = allAppWindows.size();
+ for (int i=0; i<N; i++) {
+ WindowState win = allAppWindows.get(i);
+ if (win == startingWindow || win.mAppFreezing
+ || win.mViewVisibility != View.VISIBLE
+ || win.mAttrs.type == TYPE_APPLICATION_STARTING
+ || win.mDestroying) {
+ continue;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn="
+ + win.isDrawnLw()
+ + ", isAnimating=" + win.isAnimating());
+ if (!win.isDrawnLw()) {
+ Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mSurface
+ + " pv=" + win.mPolicyVisibility
+ + " dp=" + win.mDrawPending
+ + " cdp=" + win.mCommitDrawPending
+ + " ah=" + win.mAttachedHidden
+ + " th="
+ + (win.mAppToken != null
+ ? win.mAppToken.hiddenRequested : false)
+ + " a=" + win.mAnimating);
+ }
+ }
+ numInteresting++;
+ if (win.isDrawnLw()) {
+ if (!win.isAnimating()) {
+ numVisible++;
+ }
+ nowGone = false;
+ } else if (win.isAnimating()) {
+ nowGone = false;
+ }
+ }
+
+ boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
+ + numInteresting + " visible=" + numVisible);
+ if (nowVisible != reportedVisible) {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
+ WindowManagerService.TAG, "Visibility changed in " + this
+ + ": vis=" + nowVisible);
+ reportedVisible = nowVisible;
+ Message m = service.mH.obtainMessage(
+ H.REPORT_APPLICATION_TOKEN_WINDOWS,
+ nowVisible ? 1 : 0,
+ nowGone ? 1 : 0,
+ this);
+ service.mH.sendMessage(m);
+ }
+ }
+
+ WindowState findMainWindow() {
+ int j = windows.size();
+ while (j > 0) {
+ j--;
+ WindowState win = windows.get(j);
+ if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
+ || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+ return win;
+ }
+ }
+ return null;
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ super.dump(pw, prefix);
+ if (appToken != null) {
+ pw.print(prefix); pw.println("app=true");
+ }
+ if (allAppWindows.size() > 0) {
+ pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
+ }
+ pw.print(prefix); pw.print("groupId="); pw.print(groupId);
+ pw.print(" appFullscreen="); pw.print(appFullscreen);
+ pw.print(" requestedOrientation="); pw.println(requestedOrientation);
+ pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
+ pw.print(" clientHidden="); pw.print(clientHidden);
+ pw.print(" willBeHidden="); pw.print(willBeHidden);
+ pw.print(" reportedVisible="); pw.println(reportedVisible);
+ if (paused || freezingScreen) {
+ pw.print(prefix); pw.print("paused="); pw.print(paused);
+ pw.print(" freezingScreen="); pw.println(freezingScreen);
+ }
+ if (numInterestingWindows != 0 || numDrawnWindows != 0
+ || inPendingTransaction || allDrawn) {
+ pw.print(prefix); pw.print("numInterestingWindows=");
+ pw.print(numInterestingWindows);
+ pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
+ pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
+ pw.print(" allDrawn="); pw.println(allDrawn);
+ }
+ if (animating || animation != null) {
+ pw.print(prefix); pw.print("animating="); pw.print(animating);
+ pw.print(" animation="); pw.println(animation);
+ }
+ if (hasTransformation) {
+ pw.print(prefix); pw.print("XForm: ");
+ transformation.printShortString(pw);
+ pw.println();
+ }
+ if (animLayerAdjustment != 0) {
+ pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
+ }
+ if (startingData != null || removed || firstWindowDrawn) {
+ pw.print(prefix); pw.print("startingData="); pw.print(startingData);
+ pw.print(" removed="); pw.print(removed);
+ pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
+ }
+ if (startingWindow != null || startingView != null
+ || startingDisplayed || startingMoved) {
+ pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
+ pw.print(" startingView="); pw.print(startingView);
+ pw.print(" startingDisplayed="); pw.print(startingDisplayed);
+ pw.print(" startingMoved"); pw.println(startingMoved);
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (stringName == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("AppWindowToken{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" token="); sb.append(token); sb.append('}');
+ stringName = sb.toString();
+ }
+ return stringName;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
new file mode 100644
index 0000000..1fcb869
--- /dev/null
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.util.Slog;
+import android.util.TypedValue;
+import android.view.Surface;
+import android.view.SurfaceSession;
+
+import java.io.PrintWriter;
+
+/**
+ * DimAnimator class that controls the dim animation. This holds the surface and
+ * all state used for dim animation.
+ */
+class DimAnimator {
+ Surface mDimSurface;
+ boolean mDimShown = false;
+ float mDimCurrentAlpha;
+ float mDimTargetAlpha;
+ float mDimDeltaPerMs;
+ long mLastDimAnimTime;
+
+ int mLastDimWidth, mLastDimHeight;
+
+ DimAnimator (SurfaceSession session) {
+ if (mDimSurface == null) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": CREATE");
+ try {
+ mDimSurface = new Surface(session, 0,
+ "DimSurface",
+ -1, 16, 16, PixelFormat.OPAQUE,
+ Surface.FX_SURFACE_DIM);
+ mDimSurface.setAlpha(0.0f);
+ } catch (Exception e) {
+ Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e);
+ }
+ }
+ }
+
+ /**
+ * Show the dim surface.
+ */
+ void show(int dw, int dh) {
+ if (!mDimShown) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
+ dw + "x" + dh + ")");
+ mDimShown = true;
+ try {
+ mLastDimWidth = dw;
+ mLastDimHeight = dh;
+ mDimSurface.setPosition(0, 0);
+ mDimSurface.setSize(dw, dh);
+ mDimSurface.show();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e);
+ }
+ } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
+ mLastDimWidth = dw;
+ mLastDimHeight = dh;
+ mDimSurface.setSize(dw, dh);
+ }
+ }
+
+ /**
+ * Set's the dim surface's layer and update dim parameters that will be used in
+ * {@link updateSurface} after all windows are examined.
+ */
+ void updateParameters(Resources res, WindowState w, long currentTime) {
+ mDimSurface.setLayer(w.mAnimLayer-1);
+
+ final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface
+ + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
+ if (mDimTargetAlpha != target) {
+ // If the desired dim level has changed, then
+ // start an animation to it.
+ mLastDimAnimTime = currentTime;
+ long duration = (w.mAnimating && w.mAnimation != null)
+ ? w.mAnimation.computeDurationHint()
+ : WindowManagerService.DEFAULT_DIM_DURATION;
+ if (target > mDimTargetAlpha) {
+ TypedValue tv = new TypedValue();
+ res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
+ tv, true);
+ if (tv.type == TypedValue.TYPE_FRACTION) {
+ duration = (long)tv.getFraction((float)duration, (float)duration);
+ } else if (tv.type >= TypedValue.TYPE_FIRST_INT
+ && tv.type <= TypedValue.TYPE_LAST_INT) {
+ duration = tv.data;
+ }
+ }
+ if (duration < 1) {
+ // Don't divide by zero
+ duration = 1;
+ }
+ mDimTargetAlpha = target;
+ mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
+ }
+ }
+
+ /**
+ * Updating the surface's alpha. Returns true if the animation continues, or returns
+ * false when the animation is finished and the dim surface is hidden.
+ */
+ boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
+ if (!dimming) {
+ if (mDimTargetAlpha != 0) {
+ mLastDimAnimTime = currentTime;
+ mDimTargetAlpha = 0;
+ mDimDeltaPerMs = (-mDimCurrentAlpha) / WindowManagerService.DEFAULT_DIM_DURATION;
+ }
+ }
+
+ boolean animating = false;
+ if (mLastDimAnimTime != 0) {
+ mDimCurrentAlpha += mDimDeltaPerMs
+ * (currentTime-mLastDimAnimTime);
+ boolean more = true;
+ if (displayFrozen) {
+ // If the display is frozen, there is no reason to animate.
+ more = false;
+ } else if (mDimDeltaPerMs > 0) {
+ if (mDimCurrentAlpha > mDimTargetAlpha) {
+ more = false;
+ }
+ } else if (mDimDeltaPerMs < 0) {
+ if (mDimCurrentAlpha < mDimTargetAlpha) {
+ more = false;
+ }
+ } else {
+ more = false;
+ }
+
+ // Do we need to continue animating?
+ if (more) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": alpha=" + mDimCurrentAlpha);
+ mLastDimAnimTime = currentTime;
+ mDimSurface.setAlpha(mDimCurrentAlpha);
+ animating = true;
+ } else {
+ mDimCurrentAlpha = mDimTargetAlpha;
+ mLastDimAnimTime = 0;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
+ mDimSurface.setAlpha(mDimCurrentAlpha);
+ if (!dimming) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface
+ + ": HIDE");
+ try {
+ mDimSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface");
+ }
+ mDimShown = false;
+ }
+ }
+ }
+ return animating;
+ }
+
+ public void printTo(PrintWriter pw) {
+ pw.print(" mDimShown="); pw.print(mDimShown);
+ pw.print(" current="); pw.print(mDimCurrentAlpha);
+ pw.print(" target="); pw.print(mDimTargetAlpha);
+ pw.print(" delta="); pw.print(mDimDeltaPerMs);
+ pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
new file mode 100644
index 0000000..c8f8ff3
--- /dev/null
+++ b/services/java/com/android/server/wm/DragState.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.DragEvent;
+import android.view.InputChannel;
+import android.view.InputQueue;
+import android.view.Surface;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import java.util.ArrayList;
+
+/**
+ * Drag/drop state
+ */
+class DragState {
+ final WindowManagerService mService;
+ IBinder mToken;
+ Surface mSurface;
+ int mFlags;
+ IBinder mLocalWin;
+ ClipData mData;
+ ClipDescription mDataDescription;
+ boolean mDragResult;
+ float mCurrentX, mCurrentY;
+ float mThumbOffsetX, mThumbOffsetY;
+ InputChannel mServerChannel, mClientChannel;
+ WindowState mTargetWindow;
+ ArrayList<WindowState> mNotifiedWindows;
+ boolean mDragInProgress;
+
+ private final Region mTmpRegion = new Region();
+
+ DragState(WindowManagerService service, IBinder token, Surface surface,
+ int flags, IBinder localWin) {
+ mService = service;
+ mToken = token;
+ mSurface = surface;
+ mFlags = flags;
+ mLocalWin = localWin;
+ mNotifiedWindows = new ArrayList<WindowState>();
+ }
+
+ void reset() {
+ if (mSurface != null) {
+ mSurface.destroy();
+ }
+ mSurface = null;
+ mFlags = 0;
+ mLocalWin = null;
+ mToken = null;
+ mData = null;
+ mThumbOffsetX = mThumbOffsetY = 0;
+ mNotifiedWindows = null;
+ }
+
+ void register() {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "registering drag input channel");
+ if (mClientChannel != null) {
+ Slog.e(WindowManagerService.TAG, "Duplicate register of drag input channel");
+ } else {
+ InputChannel[] channels = InputChannel.openInputChannelPair("drag");
+ mServerChannel = channels[0];
+ mClientChannel = channels[1];
+ mService.mInputManager.registerInputChannel(mServerChannel, null);
+ InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler,
+ mService.mH.getLooper().getQueue());
+ }
+ }
+
+ void unregister() {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "unregistering drag input channel");
+ if (mClientChannel == null) {
+ Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel");
+ } else {
+ mService.mInputManager.unregisterInputChannel(mServerChannel);
+ InputQueue.unregisterInputChannel(mClientChannel);
+ mClientChannel.dispose();
+ mServerChannel.dispose();
+ mClientChannel = null;
+ mServerChannel = null;
+ }
+ }
+
+ int getDragLayerLw() {
+ return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
+ * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ }
+
+ /* call out to each visible window/session informing it about the drag
+ */
+ void broadcastDragStartedLw(final float touchX, final float touchY) {
+ // Cache a base-class instance of the clip metadata so that parceling
+ // works correctly in calling out to the apps.
+ mDataDescription = (mData != null) ? mData.getDescription() : null;
+ mNotifiedWindows.clear();
+ mDragInProgress = true;
+
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
+ }
+
+ final int N = mService.mWindows.size();
+ for (int i = 0; i < N; i++) {
+ sendDragStartedLw(mService.mWindows.get(i), touchX, touchY, mDataDescription);
+ }
+ }
+
+ /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
+ * designated window is potentially a drop recipient. There are race situations
+ * around DRAG_ENDED broadcast, so we make sure that once we've declared that
+ * the drag has ended, we never send out another DRAG_STARTED for this drag action.
+ *
+ * This method clones the 'event' parameter if it's being delivered to the same
+ * process, so it's safe for the caller to call recycle() on the event afterwards.
+ */
+ private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
+ ClipDescription desc) {
+ // Don't actually send the event if the drag is supposed to be pinned
+ // to the originating window but 'newWin' is not that window.
+ if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
+ final IBinder winBinder = newWin.mClient.asBinder();
+ if (winBinder != mLocalWin) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Not dispatching local DRAG_STARTED to " + newWin);
+ }
+ return;
+ }
+ }
+
+ if (mDragInProgress && newWin.isPotentialDragTarget()) {
+ DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
+ touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
+ null, desc, null, false);
+ try {
+ newWin.mClient.dispatchDragEvent(event);
+ // track each window that we've notified that the drag is starting
+ mNotifiedWindows.add(newWin);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "Unable to drag-start window " + newWin);
+ } finally {
+ // if the callee was local, the dispatch has already recycled the event
+ if (Process.myPid() != newWin.mSession.mPid) {
+ event.recycle();
+ }
+ }
+ }
+ }
+
+ /* helper - construct and send a DRAG_STARTED event only if the window has not
+ * previously been notified, i.e. it became visible after the drag operation
+ * was begun. This is a rare case.
+ */
+ void sendDragStartedIfNeededLw(WindowState newWin) {
+ if (mDragInProgress) {
+ // If we have sent the drag-started, we needn't do so again
+ for (WindowState ws : mNotifiedWindows) {
+ if (ws == newWin) {
+ return;
+ }
+ }
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "need to send DRAG_STARTED to new window " + newWin);
+ }
+ sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
+ }
+ }
+
+ void broadcastDragEndedLw() {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED");
+ }
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
+ 0, 0, null, null, null, mDragResult);
+ for (WindowState ws: mNotifiedWindows) {
+ try {
+ ws.mClient.dispatchDragEvent(evt);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "Unable to drag-end window " + ws);
+ }
+ }
+ mNotifiedWindows.clear();
+ mDragInProgress = false;
+ evt.recycle();
+ }
+
+ void endDragLw() {
+ mService.mDragState.broadcastDragEndedLw();
+
+ // stop intercepting input
+ mService.mDragState.unregister();
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+
+ // free our resources and drop all the object references
+ mService.mDragState.reset();
+ mService.mDragState = null;
+
+ if (WindowManagerService.DEBUG_ORIENTATION) Slog.d(WindowManagerService.TAG, "Performing post-drag rotation");
+ boolean changed = mService.setRotationUncheckedLocked(
+ WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
+ if (changed) {
+ mService.mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+ }
+ }
+
+ void notifyMoveLw(float x, float y) {
+ final int myPid = Process.myPid();
+
+ // Move the surface to the given touch
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
+ Surface.openTransaction();
+ try {
+ mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DRAG "
+ + mSurface + ": pos=(" +
+ (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
+ }
+
+ // Tell the affected window
+ WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "No touched win at x=" + x + " y=" + y);
+ return;
+ }
+ if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
+ final IBinder touchedBinder = touchedWin.mClient.asBinder();
+ if (touchedBinder != mLocalWin) {
+ // This drag is pinned only to the originating window, but the drag
+ // point is outside that window. Pretend it's over empty space.
+ touchedWin = null;
+ }
+ }
+ try {
+ // have we dragged over a new window?
+ if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow);
+ }
+ // force DRAG_EXITED_EVENT if appropriate
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
+ x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
+ null, null, null, false);
+ mTargetWindow.mClient.dispatchDragEvent(evt);
+ if (myPid != mTargetWindow.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ if (touchedWin != null) {
+ if (false && WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin);
+ }
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, null, null, false);
+ touchedWin.mClient.dispatchDragEvent(evt);
+ if (myPid != touchedWin.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "can't send drag notification to windows");
+ }
+ mTargetWindow = touchedWin;
+ }
+
+ // Tell the drop target about the data. Returns 'true' if we can immediately
+ // dispatch the global drag-ended message, 'false' if we need to wait for a
+ // result from the recipient.
+ boolean notifyDropLw(float x, float y) {
+ WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ // "drop" outside a valid window -- no recipient to apply a
+ // timeout to, and we can send the drag-ended message immediately.
+ mDragResult = false;
+ return true;
+ }
+
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DROP to " + touchedWin);
+ }
+ final int myPid = Process.myPid();
+ final IBinder token = touchedWin.mClient.asBinder();
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, null, mData, false);
+ try {
+ touchedWin.mClient.dispatchDragEvent(evt);
+
+ // 5 second timeout for this window to respond to the drop
+ mService.mH.removeMessages(H.DRAG_END_TIMEOUT, token);
+ Message msg = mService.mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
+ mService.mH.sendMessageDelayed(msg, 5000);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "can't send drop notification to win " + touchedWin);
+ return true;
+ } finally {
+ if (myPid != touchedWin.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ mToken = token;
+ return false;
+ }
+
+ // Find the visible, touch-deliverable window under the given point
+ private WindowState getTouchedWinAtPointLw(float xf, float yf) {
+ WindowState touchedWin = null;
+ final int x = (int) xf;
+ final int y = (int) yf;
+ final ArrayList<WindowState> windows = mService.mWindows;
+ final int N = windows.size();
+ for (int i = N - 1; i >= 0; i--) {
+ WindowState child = windows.get(i);
+ final int flags = child.mAttrs.flags;
+ if (!child.isVisibleLw()) {
+ // not visible == don't tell about drags
+ continue;
+ }
+ if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
+ // not touchable == don't tell about drags
+ continue;
+ }
+
+ child.getTouchableRegion(mTmpRegion);
+
+ final int touchFlags = flags &
+ (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+ if (mTmpRegion.contains(x, y) || touchFlags == 0) {
+ // Found it
+ touchedWin = child;
+ break;
+ }
+ }
+
+ return touchedWin;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/FadeInOutAnimation.java b/services/java/com/android/server/wm/FadeInOutAnimation.java
new file mode 100644
index 0000000..06f7657
--- /dev/null
+++ b/services/java/com/android/server/wm/FadeInOutAnimation.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+/**
+ * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
+ * This is used for opening/closing transition for apps in compatible mode.
+ */
+class FadeInOutAnimation extends Animation {
+ boolean mFadeIn;
+
+ public FadeInOutAnimation(boolean fadeIn) {
+ setInterpolator(new AccelerateInterpolator());
+ setDuration(WindowManagerService.DEFAULT_FADE_IN_OUT_DURATION);
+ mFadeIn = fadeIn;
+ }
+
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ float x = interpolatedTime;
+ if (!mFadeIn) {
+ x = 1.0f - x; // reverse the interpolation for fade out
+ }
+ t.setAlpha(x);
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/InputApplication.java b/services/java/com/android/server/wm/InputApplication.java
similarity index 96%
rename from services/java/com/android/server/InputApplication.java
rename to services/java/com/android/server/wm/InputApplication.java
index ae09484..e04fd31 100644
--- a/services/java/com/android/server/InputApplication.java
+++ b/services/java/com/android/server/wm/InputApplication.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
/**
* Describes input-related application properties for use by the input dispatcher.
diff --git a/services/java/com/android/server/InputApplicationHandle.java b/services/java/com/android/server/wm/InputApplicationHandle.java
similarity index 87%
rename from services/java/com/android/server/InputApplicationHandle.java
rename to services/java/com/android/server/wm/InputApplicationHandle.java
index d396d11..64c8e7e 100644
--- a/services/java/com/android/server/InputApplicationHandle.java
+++ b/services/java/com/android/server/wm/InputApplicationHandle.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
/**
* Functions as a handle for an application that can receive input.
@@ -29,11 +30,11 @@
private int ptr;
// The window manager's application window token.
- public final WindowManagerService.AppWindowToken appWindowToken;
+ public final AppWindowToken appWindowToken;
private native void nativeDispose();
- public InputApplicationHandle(WindowManagerService.AppWindowToken appWindowToken) {
+ public InputApplicationHandle(AppWindowToken appWindowToken) {
this.appWindowToken = appWindowToken;
}
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/wm/InputManager.java
similarity index 99%
rename from services/java/com/android/server/InputManager.java
rename to services/java/com/android/server/wm/InputManager.java
index 8d249ff..80a2a96 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import com.android.internal.util.XmlUtils;
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
new file mode 100644
index 0000000..34f3618
--- /dev/null
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -0,0 +1,364 @@
+/**
+ *
+ */
+package com.android.server.wm;
+
+import android.graphics.Rect;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+
+final class InputMonitor {
+ private final WindowManagerService mService;
+
+ // Current window with input focus for keys and other non-touch events. May be null.
+ private WindowState mInputFocus;
+
+ // When true, prevents input dispatch from proceeding until set to false again.
+ private boolean mInputDispatchFrozen;
+
+ // When true, input dispatch proceeds normally. Otherwise all events are dropped.
+ private boolean mInputDispatchEnabled = true;
+
+ // When true, need to call updateInputWindowsLw().
+ private boolean mUpdateInputWindowsNeeded = true;
+
+ // Temporary list of windows information to provide to the input dispatcher.
+ private InputWindowList mTempInputWindows = new InputWindowList();
+
+ // Temporary input application object to provide to the input dispatcher.
+ private InputApplication mTempInputApplication = new InputApplication();
+
+ // Set to true when the first input device configuration change notification
+ // is received to indicate that the input devices are ready.
+ private final Object mInputDevicesReadyMonitor = new Object();
+ private boolean mInputDevicesReady;
+
+ public InputMonitor(WindowManagerService service) {
+ mService = service;
+ }
+
+ /* Notifies the window manager about a broken input channel.
+ *
+ * Called by the InputManager.
+ */
+ public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
+ if (inputWindowHandle == null) {
+ return;
+ }
+
+ synchronized (mService.mWindowMap) {
+ WindowState windowState = (WindowState) inputWindowHandle.windowState;
+ Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
+ mService.removeWindowLocked(windowState.mSession, windowState);
+ }
+ }
+
+ /* Notifies the window manager about an application that is not responding.
+ * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
+ *
+ * Called by the InputManager.
+ */
+ public long notifyANR(InputApplicationHandle inputApplicationHandle,
+ InputWindowHandle inputWindowHandle) {
+ AppWindowToken appWindowToken = null;
+ if (inputWindowHandle != null) {
+ synchronized (mService.mWindowMap) {
+ WindowState windowState = (WindowState) inputWindowHandle.windowState;
+ if (windowState != null) {
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
+ + windowState.mAttrs.getTitle());
+ appWindowToken = windowState.mAppToken;
+ }
+ }
+ }
+
+ if (appWindowToken == null && inputApplicationHandle != null) {
+ appWindowToken = inputApplicationHandle.appWindowToken;
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to application "
+ + appWindowToken.stringName);
+ }
+
+ if (appWindowToken != null && appWindowToken.appToken != null) {
+ try {
+ // Notify the activity manager about the timeout and let it decide whether
+ // to abort dispatching or keep waiting.
+ boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
+ if (! abort) {
+ // The activity manager declined to abort dispatching.
+ // Wait a bit longer and timeout again later.
+ return appWindowToken.inputDispatchingTimeoutNanos;
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+ return 0; // abort dispatching
+ }
+
+ private void addDragInputWindowLw(InputWindowList windowList) {
+ final InputWindow inputWindow = windowList.add();
+ inputWindow.inputChannel = mService.mDragState.mServerChannel;
+ inputWindow.name = "drag";
+ inputWindow.layoutParamsFlags = 0;
+ inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
+ inputWindow.dispatchingTimeoutNanos = WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ inputWindow.visible = true;
+ inputWindow.canReceiveKeys = false;
+ inputWindow.hasFocus = true;
+ inputWindow.hasWallpaper = false;
+ inputWindow.paused = false;
+ inputWindow.layer = mService.mDragState.getDragLayerLw();
+ inputWindow.ownerPid = Process.myPid();
+ inputWindow.ownerUid = Process.myUid();
+
+ // The drag window covers the entire display
+ inputWindow.frameLeft = 0;
+ inputWindow.frameTop = 0;
+ inputWindow.frameRight = mService.mDisplay.getWidth();
+ inputWindow.frameBottom = mService.mDisplay.getHeight();
+
+ // The drag window cannot receive new touches.
+ inputWindow.touchableRegion.setEmpty();
+ }
+
+ public void setUpdateInputWindowsNeededLw() {
+ mUpdateInputWindowsNeeded = true;
+ }
+
+ /* Updates the cached window information provided to the input dispatcher. */
+ public void updateInputWindowsLw(boolean force) {
+ if (!force && !mUpdateInputWindowsNeeded) {
+ return;
+ }
+ mUpdateInputWindowsNeeded = false;
+
+ // Populate the input window list with information about all of the windows that
+ // could potentially receive input.
+ // As an optimization, we could try to prune the list of windows but this turns
+ // out to be difficult because only the native code knows for sure which window
+ // currently has touch focus.
+ final ArrayList<WindowState> windows = mService.mWindows;
+
+ // If there's a drag in flight, provide a pseudowindow to catch drag input
+ final boolean inDrag = (mService.mDragState != null);
+ if (inDrag) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Log.d(WindowManagerService.TAG, "Inserting drag window");
+ }
+ addDragInputWindowLw(mTempInputWindows);
+ }
+
+ final int N = windows.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final WindowState child = windows.get(i);
+ if (child.mInputChannel == null || child.mRemoved) {
+ // Skip this window because it cannot possibly receive input.
+ continue;
+ }
+
+ final int flags = child.mAttrs.flags;
+ final int type = child.mAttrs.type;
+
+ final boolean hasFocus = (child == mInputFocus);
+ final boolean isVisible = child.isVisibleLw();
+ final boolean hasWallpaper = (child == mService.mWallpaperTarget)
+ && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
+
+ // If there's a drag in progress and 'child' is a potential drop target,
+ // make sure it's been told about the drag
+ if (inDrag && isVisible) {
+ mService.mDragState.sendDragStartedIfNeededLw(child);
+ }
+
+ // Add a window to our list of input windows.
+ final InputWindow inputWindow = mTempInputWindows.add();
+ inputWindow.inputWindowHandle = child.mInputWindowHandle;
+ inputWindow.inputChannel = child.mInputChannel;
+ inputWindow.name = child.toString();
+ inputWindow.layoutParamsFlags = flags;
+ inputWindow.layoutParamsType = type;
+ inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
+ inputWindow.visible = isVisible;
+ inputWindow.canReceiveKeys = child.canReceiveKeys();
+ inputWindow.hasFocus = hasFocus;
+ inputWindow.hasWallpaper = hasWallpaper;
+ inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
+ inputWindow.layer = child.mLayer;
+ inputWindow.ownerPid = child.mSession.mPid;
+ inputWindow.ownerUid = child.mSession.mUid;
+
+ final Rect frame = child.mFrame;
+ inputWindow.frameLeft = frame.left;
+ inputWindow.frameTop = frame.top;
+ inputWindow.frameRight = frame.right;
+ inputWindow.frameBottom = frame.bottom;
+
+ child.getTouchableRegion(inputWindow.touchableRegion);
+ }
+
+ // Send windows to native code.
+ mService.mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
+
+ // Clear the list in preparation for the next round.
+ // Also avoids keeping InputChannel objects referenced unnecessarily.
+ mTempInputWindows.clear();
+ }
+
+ /* Notifies that the input device configuration has changed. */
+ public void notifyConfigurationChanged() {
+ mService.sendNewConfiguration();
+
+ synchronized (mInputDevicesReadyMonitor) {
+ if (!mInputDevicesReady) {
+ mInputDevicesReady = true;
+ mInputDevicesReadyMonitor.notifyAll();
+ }
+ }
+ }
+
+ /* Waits until the built-in input devices have been configured. */
+ public boolean waitForInputDevicesReady(long timeoutMillis) {
+ synchronized (mInputDevicesReadyMonitor) {
+ if (!mInputDevicesReady) {
+ try {
+ mInputDevicesReadyMonitor.wait(timeoutMillis);
+ } catch (InterruptedException ex) {
+ }
+ }
+ return mInputDevicesReady;
+ }
+ }
+
+ /* Notifies that the lid switch changed state. */
+ public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+ mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+ }
+
+ /* Provides an opportunity for the window manager policy to intercept early key
+ * processing as soon as the key has been read from the device. */
+ public int interceptKeyBeforeQueueing(
+ KeyEvent event, int policyFlags, boolean isScreenOn) {
+ return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
+ }
+
+ /* Provides an opportunity for the window manager policy to process a key before
+ * ordinary dispatch. */
+ public boolean interceptKeyBeforeDispatching(
+ InputWindowHandle focus, KeyEvent event, int policyFlags) {
+ WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
+ return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
+ }
+
+ /* Provides an opportunity for the window manager policy to process a key that
+ * the application did not handle. */
+ public KeyEvent dispatchUnhandledKey(
+ InputWindowHandle focus, KeyEvent event, int policyFlags) {
+ WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
+ return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
+ }
+
+ /* Called when the current input focus changes.
+ * Layer assignment is assumed to be complete by the time this is called.
+ */
+ public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.d(WindowManagerService.TAG, "Input focus has changed to " + newWindow);
+ }
+
+ if (newWindow != mInputFocus) {
+ if (newWindow != null && newWindow.canReceiveKeys()) {
+ // Displaying a window implicitly causes dispatching to be unpaused.
+ // This is to protect against bugs if someone pauses dispatching but
+ // forgets to resume.
+ newWindow.mToken.paused = false;
+ }
+
+ mInputFocus = newWindow;
+ setUpdateInputWindowsNeededLw();
+
+ if (updateInputWindows) {
+ updateInputWindowsLw(false /*force*/);
+ }
+ }
+ }
+
+ public void setFocusedAppLw(AppWindowToken newApp) {
+ // Focused app has changed.
+ if (newApp == null) {
+ mService.mInputManager.setFocusedApplication(null);
+ } else {
+ mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
+ mTempInputApplication.name = newApp.toString();
+ mTempInputApplication.dispatchingTimeoutNanos =
+ newApp.inputDispatchingTimeoutNanos;
+
+ mService.mInputManager.setFocusedApplication(mTempInputApplication);
+
+ mTempInputApplication.recycle();
+ }
+ }
+
+ public void pauseDispatchingLw(WindowToken window) {
+ if (! window.paused) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Pausing WindowToken " + window);
+ }
+
+ window.paused = true;
+ updateInputWindowsLw(true /*force*/);
+ }
+ }
+
+ public void resumeDispatchingLw(WindowToken window) {
+ if (window.paused) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Resuming WindowToken " + window);
+ }
+
+ window.paused = false;
+ updateInputWindowsLw(true /*force*/);
+ }
+ }
+
+ public void freezeInputDispatchingLw() {
+ if (! mInputDispatchFrozen) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Freezing input dispatching");
+ }
+
+ mInputDispatchFrozen = true;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ public void thawInputDispatchingLw() {
+ if (mInputDispatchFrozen) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Thawing input dispatching");
+ }
+
+ mInputDispatchFrozen = false;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ public void setEventDispatchingLw(boolean enabled) {
+ if (mInputDispatchEnabled != enabled) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Setting event dispatching to " + enabled);
+ }
+
+ mInputDispatchEnabled = enabled;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ private void updateInputDispatchModeLw() {
+ mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/InputWindow.java b/services/java/com/android/server/wm/InputWindow.java
similarity index 98%
rename from services/java/com/android/server/InputWindow.java
rename to services/java/com/android/server/wm/InputWindow.java
index 2c2cdfe..e3eb473 100644
--- a/services/java/com/android/server/InputWindow.java
+++ b/services/java/com/android/server/wm/InputWindow.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import android.graphics.Region;
import android.view.InputChannel;
diff --git a/services/java/com/android/server/InputWindowHandle.java b/services/java/com/android/server/wm/InputWindowHandle.java
similarity index 97%
rename from services/java/com/android/server/InputWindowHandle.java
rename to services/java/com/android/server/wm/InputWindowHandle.java
index 4b92939..cc508c6 100644
--- a/services/java/com/android/server/InputWindowHandle.java
+++ b/services/java/com/android/server/wm/InputWindowHandle.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import android.view.WindowManagerPolicy;
diff --git a/services/java/com/android/server/InputWindowList.java b/services/java/com/android/server/wm/InputWindowList.java
similarity index 98%
rename from services/java/com/android/server/InputWindowList.java
rename to services/java/com/android/server/wm/InputWindowList.java
index 1cbb2cc..6077337 100644
--- a/services/java/com/android/server/InputWindowList.java
+++ b/services/java/com/android/server/wm/InputWindowList.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
/**
diff --git a/services/java/com/android/server/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
similarity index 99%
rename from services/java/com/android/server/ScreenRotationAnimation.java
rename to services/java/com/android/server/wm/ScreenRotationAnimation.java
index ef00b08f..4356ce5 100644
--- a/services/java/com/android/server/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server; // TODO: use com.android.server.wm, once things move there
+package com.android.server.wm;
import android.content.Context;
import android.graphics.Bitmap;
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
new file mode 100644
index 0000000..b9db177
--- /dev/null
+++ b/services/java/com/android/server/wm/Session.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
+import com.android.internal.view.IInputMethodManager;
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.SurfaceSession;
+import android.view.WindowManager;
+
+import java.io.PrintWriter;
+
+/**
+ * This class represents an active client session. There is generally one
+ * Session object per process that is interacting with the window manager.
+ */
+final class Session extends IWindowSession.Stub
+ implements IBinder.DeathRecipient {
+ final WindowManagerService mService;
+ final IInputMethodClient mClient;
+ final IInputContext mInputContext;
+ final int mUid;
+ final int mPid;
+ final String mStringName;
+ SurfaceSession mSurfaceSession;
+ int mNumWindow = 0;
+ boolean mClientDead = false;
+
+ public Session(WindowManagerService service, IInputMethodClient client,
+ IInputContext inputContext) {
+ mService = service;
+ mClient = client;
+ mInputContext = inputContext;
+ mUid = Binder.getCallingUid();
+ mPid = Binder.getCallingPid();
+ StringBuilder sb = new StringBuilder();
+ sb.append("Session{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" uid ");
+ sb.append(mUid);
+ sb.append("}");
+ mStringName = sb.toString();
+
+ synchronized (mService.mWindowMap) {
+ if (mService.mInputMethodManager == null && mService.mHaveInputMethods) {
+ IBinder b = ServiceManager.getService(
+ Context.INPUT_METHOD_SERVICE);
+ mService.mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
+ }
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ // Note: it is safe to call in to the input method manager
+ // here because we are not holding our lock.
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.addClient(client, inputContext,
+ mUid, mPid);
+ } else {
+ client.setUsingInputMethod(false);
+ }
+ client.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ // The caller has died, so we can just forget about this.
+ try {
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.removeClient(client);
+ }
+ } catch (RemoteException ee) {
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ try {
+ return super.onTransact(code, data, reply, flags);
+ } catch (RuntimeException e) {
+ // Log all 'real' exceptions thrown to the caller
+ if (!(e instanceof SecurityException)) {
+ Slog.e(WindowManagerService.TAG, "Window Session Crash", e);
+ }
+ throw e;
+ }
+ }
+
+ public void binderDied() {
+ // Note: it is safe to call in to the input method manager
+ // here because we are not holding our lock.
+ try {
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.removeClient(mClient);
+ }
+ } catch (RemoteException e) {
+ }
+ synchronized(mService.mWindowMap) {
+ mClient.asBinder().unlinkToDeath(this, 0);
+ mClientDead = true;
+ killSessionLocked();
+ }
+ }
+
+ public int add(IWindow window, WindowManager.LayoutParams attrs,
+ int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
+ return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets,
+ outInputChannel);
+ }
+
+ public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
+ int viewVisibility, Rect outContentInsets) {
+ return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
+ }
+
+ public void remove(IWindow window) {
+ mService.removeWindow(this, window);
+ }
+
+ public int relayout(IWindow window, WindowManager.LayoutParams attrs,
+ int requestedWidth, int requestedHeight, int viewFlags,
+ boolean insetsPending, Rect outFrame, Rect outContentInsets,
+ Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
+ //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
+ int res = mService.relayoutWindow(this, window, attrs,
+ requestedWidth, requestedHeight, viewFlags, insetsPending,
+ outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
+ //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
+ return res;
+ }
+
+ public void setTransparentRegion(IWindow window, Region region) {
+ mService.setTransparentRegionWindow(this, window, region);
+ }
+
+ public void setInsets(IWindow window, int touchableInsets,
+ Rect contentInsets, Rect visibleInsets, Region touchableArea) {
+ mService.setInsetsWindow(this, window, touchableInsets, contentInsets,
+ visibleInsets, touchableArea);
+ }
+
+ public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+ mService.getWindowDisplayFrame(this, window, outDisplayFrame);
+ }
+
+ public void finishDrawing(IWindow window) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "IWindow finishDrawing called for " + window);
+ mService.finishDrawingWindow(this, window);
+ }
+
+ public void setInTouchMode(boolean mode) {
+ synchronized(mService.mWindowMap) {
+ mService.mInTouchMode = mode;
+ }
+ }
+
+ public boolean getInTouchMode() {
+ synchronized(mService.mWindowMap) {
+ return mService.mInTouchMode;
+ }
+ }
+
+ public boolean performHapticFeedback(IWindow window, int effectId,
+ boolean always) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mService.mPolicy.performHapticFeedbackLw(
+ mService.windowForClientLocked(this, window, true),
+ effectId, always);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ /* Drag/drop */
+ public IBinder prepareDrag(IWindow window, int flags,
+ int width, int height, Surface outSurface) {
+ return mService.prepareDragSurface(window, mSurfaceSession, flags,
+ width, height, outSurface);
+ }
+
+ public boolean performDrag(IWindow window, IBinder dragToken,
+ float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+ ClipData data) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "perform drag: win=" + window + " data=" + data);
+ }
+
+ synchronized (mService.mWindowMap) {
+ if (mService.mDragState == null) {
+ Slog.w(WindowManagerService.TAG, "No drag prepared");
+ throw new IllegalStateException("performDrag() without prepareDrag()");
+ }
+
+ if (dragToken != mService.mDragState.mToken) {
+ Slog.w(WindowManagerService.TAG, "Performing mismatched drag");
+ throw new IllegalStateException("performDrag() does not match prepareDrag()");
+ }
+
+ WindowState callingWin = mService.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(WindowManagerService.TAG, "Bad requesting window " + window);
+ return false; // !!! TODO: throw here?
+ }
+
+ // !!! TODO: if input is not still focused on the initiating window, fail
+ // the drag initiation (e.g. an alarm window popped up just as the application
+ // called performDrag()
+
+ mService.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
+
+ // !!! TODO: extract the current touch (x, y) in screen coordinates. That
+ // will let us eliminate the (touchX,touchY) parameters from the API.
+
+ // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
+ // the actual drag event dispatch stuff in the dragstate
+
+ mService.mDragState.register();
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+ if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
+ mService.mDragState.mServerChannel)) {
+ Slog.e(WindowManagerService.TAG, "Unable to transfer touch focus");
+ mService.mDragState.unregister();
+ mService.mDragState = null;
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+ return false;
+ }
+
+ mService.mDragState.mData = data;
+ mService.mDragState.mCurrentX = touchX;
+ mService.mDragState.mCurrentY = touchY;
+ mService.mDragState.broadcastDragStartedLw(touchX, touchY);
+
+ // remember the thumb offsets for later
+ mService.mDragState.mThumbOffsetX = thumbCenterX;
+ mService.mDragState.mThumbOffsetY = thumbCenterY;
+
+ // Make the surface visible at the proper location
+ final Surface surface = mService.mDragState.mSurface;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
+ Surface.openTransaction();
+ try {
+ surface.setPosition((int)(touchX - thumbCenterX),
+ (int)(touchY - thumbCenterY));
+ surface.setAlpha(.7071f);
+ surface.setLayer(mService.mDragState.getDragLayerLw());
+ surface.show();
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
+ }
+ }
+
+ return true; // success!
+ }
+
+ public void reportDropResult(IWindow window, boolean consumed) {
+ IBinder token = window.asBinder();
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drop result=" + consumed + " reported by " + token);
+ }
+
+ synchronized (mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (mService.mDragState == null || mService.mDragState.mToken != token) {
+ Slog.w(WindowManagerService.TAG, "Invalid drop-result claim by " + window);
+ throw new IllegalStateException("reportDropResult() by non-recipient");
+ }
+
+ // The right window has responded, even if it's no longer around,
+ // so be sure to halt the timeout even if the later WindowState
+ // lookup fails.
+ mService.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
+ WindowState callingWin = mService.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(WindowManagerService.TAG, "Bad result-reporting window " + window);
+ return; // !!! TODO: throw here?
+ }
+
+ mService.mDragState.mDragResult = consumed;
+ mService.mDragState.endDragLw();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void dragRecipientEntered(IWindow window) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drag into new candidate view @ " + window.asBinder());
+ }
+ }
+
+ public void dragRecipientExited(IWindow window) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drag from old candidate view @ " + window.asBinder());
+ }
+ }
+
+ public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mService.setWindowWallpaperPositionLocked(
+ mService.windowForClientLocked(this, window, true),
+ x, y, xStep, yStep);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void wallpaperOffsetsComplete(IBinder window) {
+ mService.wallpaperOffsetsComplete(window);
+ }
+
+ public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mService.sendWindowWallpaperCommandLocked(
+ mService.windowForClientLocked(this, window, true),
+ action, x, y, z, extras, sync);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void wallpaperCommandComplete(IBinder window, Bundle result) {
+ mService.wallpaperCommandComplete(window, result);
+ }
+
+ void windowAddedLocked() {
+ if (mSurfaceSession == null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
+ mSurfaceSession = new SurfaceSession();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, " NEW SURFACE SESSION " + mSurfaceSession);
+ mService.mSessions.add(this);
+ }
+ mNumWindow++;
+ }
+
+ void windowRemovedLocked() {
+ mNumWindow--;
+ killSessionLocked();
+ }
+
+ void killSessionLocked() {
+ if (mNumWindow <= 0 && mClientDead) {
+ mService.mSessions.remove(this);
+ if (mSurfaceSession != null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Last window removed from " + this
+ + ", destroying " + mSurfaceSession);
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, " KILL SURFACE SESSION " + mSurfaceSession);
+ try {
+ mSurfaceSession.kill();
+ } catch (Exception e) {
+ Slog.w(WindowManagerService.TAG, "Exception thrown when killing surface session "
+ + mSurfaceSession + " in session " + this
+ + ": " + e.toString());
+ }
+ mSurfaceSession = null;
+ }
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
+ pw.print(" mClientDead="); pw.print(mClientDead);
+ pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
+ }
+
+ @Override
+ public String toString() {
+ return mStringName;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java
new file mode 100644
index 0000000..625fcfe
--- /dev/null
+++ b/services/java/com/android/server/wm/StartingData.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+final class StartingData {
+ final String pkg;
+ final int theme;
+ final CharSequence nonLocalizedLabel;
+ final int labelRes;
+ final int icon;
+ final int windowFlags;
+
+ StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
+ int _labelRes, int _icon, int _windowFlags) {
+ pkg = _pkg;
+ theme = _theme;
+ nonLocalizedLabel = _nonLocalizedLabel;
+ labelRes = _labelRes;
+ icon = _icon;
+ windowFlags = _windowFlags;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java
similarity index 96%
rename from services/java/com/android/server/StrictModeFlash.java
rename to services/java/com/android/server/wm/StrictModeFlash.java
index 0a6c625..2c62080 100644
--- a/services/java/com/android/server/StrictModeFlash.java
+++ b/services/java/com/android/server/wm/StrictModeFlash.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.server; // TODO: use com.android.server.wm, once things move there
+package com.android.server.wm;
+
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.DisplayMetrics;
diff --git a/services/java/com/android/server/ViewServer.java b/services/java/com/android/server/wm/ViewServer.java
similarity index 98%
rename from services/java/com/android/server/ViewServer.java
rename to services/java/com/android/server/wm/ViewServer.java
index 7b5d18a..cebd5e7 100644
--- a/services/java/com/android/server/ViewServer.java
+++ b/services/java/com/android/server/wm/ViewServer.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
import android.util.Slog;
@@ -33,7 +34,7 @@
/**
* The ViewServer is local socket server that can be used to communicate with the
* views of the opened windows. Communication with the views is ensured by the
- * {@link com.android.server.WindowManagerService} and is a cross-process operation.
+ * {@link com.android.server.wm.WindowManagerService} and is a cross-process operation.
*
* {@hide}
*/
diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java
new file mode 100644
index 0000000..22126f3
--- /dev/null
+++ b/services/java/com/android/server/wm/Watermark.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.Paint.FontMetricsInt;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceSession;
+import android.view.Surface.OutOfResourcesException;
+
+/**
+ * Displays a watermark on top of the window manager's windows.
+ */
+class Watermark {
+ final String[] mTokens;
+ final String mText;
+ final Paint mTextPaint;
+ final int mTextWidth;
+ final int mTextHeight;
+ final int mTextAscent;
+ final int mTextDescent;
+ final int mDeltaX;
+ final int mDeltaY;
+
+ Surface mSurface;
+ int mLastDW;
+ int mLastDH;
+ boolean mDrawNeeded;
+
+ Watermark(Display display, SurfaceSession session, String[] tokens) {
+ final DisplayMetrics dm = new DisplayMetrics();
+ display.getMetrics(dm);
+
+ if (false) {
+ Log.i(WindowManagerService.TAG, "*********************** WATERMARK");
+ for (int i=0; i<tokens.length; i++) {
+ Log.i(WindowManagerService.TAG, " TOKEN #" + i + ": " + tokens[i]);
+ }
+ }
+
+ mTokens = tokens;
+
+ StringBuilder builder = new StringBuilder(32);
+ int len = mTokens[0].length();
+ len = len & ~1;
+ for (int i=0; i<len; i+=2) {
+ int c1 = mTokens[0].charAt(i);
+ int c2 = mTokens[0].charAt(i+1);
+ if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
+ else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
+ else c1 -= '0';
+ if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
+ else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
+ else c2 -= '0';
+ builder.append((char)(255-((c1*16)+c2)));
+ }
+ mText = builder.toString();
+ if (false) {
+ Log.i(WindowManagerService.TAG, "Final text: " + mText);
+ }
+
+ int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
+ TypedValue.COMPLEX_UNIT_DIP, 20, dm);
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setTextSize(fontSize);
+ mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
+
+ FontMetricsInt fm = mTextPaint.getFontMetricsInt();
+ mTextWidth = (int)mTextPaint.measureText(mText);
+ mTextAscent = fm.ascent;
+ mTextDescent = fm.descent;
+ mTextHeight = fm.descent - fm.ascent;
+
+ mDeltaX = WindowManagerService.getPropertyInt(tokens, 2,
+ TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
+ mDeltaY = WindowManagerService.getPropertyInt(tokens, 3,
+ TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
+ int shadowColor = WindowManagerService.getPropertyInt(tokens, 4,
+ TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
+ int color = WindowManagerService.getPropertyInt(tokens, 5,
+ TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
+ int shadowRadius = WindowManagerService.getPropertyInt(tokens, 6,
+ TypedValue.COMPLEX_UNIT_PX, 7, dm);
+ int shadowDx = WindowManagerService.getPropertyInt(tokens, 8,
+ TypedValue.COMPLEX_UNIT_PX, 0, dm);
+ int shadowDy = WindowManagerService.getPropertyInt(tokens, 9,
+ TypedValue.COMPLEX_UNIT_PX, 0, dm);
+
+ mTextPaint.setColor(color);
+ mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
+
+ try {
+ mSurface = new Surface(session, 0,
+ "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
+ mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100);
+ mSurface.setPosition(0, 0);
+ mSurface.show();
+ } catch (OutOfResourcesException e) {
+ }
+ }
+
+ void positionSurface(int dw, int dh) {
+ if (mLastDW != dw || mLastDH != dh) {
+ mLastDW = dw;
+ mLastDH = dh;
+ mSurface.setSize(dw, dh);
+ mDrawNeeded = true;
+ }
+ }
+
+ void drawIfNeeded() {
+ if (mDrawNeeded) {
+ final int dw = mLastDW;
+ final int dh = mLastDH;
+
+ mDrawNeeded = false;
+ Rect dirty = new Rect(0, 0, dw, dh);
+ Canvas c = null;
+ try {
+ c = mSurface.lockCanvas(dirty);
+ } catch (IllegalArgumentException e) {
+ } catch (OutOfResourcesException e) {
+ }
+ if (c != null) {
+ c.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ int deltaX = mDeltaX;
+ int deltaY = mDeltaY;
+
+ // deltaX shouldn't be close to a round fraction of our
+ // x step, or else things will line up too much.
+ int div = (dw+mTextWidth)/deltaX;
+ int rem = (dw+mTextWidth) - (div*deltaX);
+ int qdelta = deltaX/4;
+ if (rem < qdelta || rem > (deltaX-qdelta)) {
+ deltaX += deltaX/3;
+ }
+
+ int y = -mTextHeight;
+ int x = -mTextWidth;
+ while (y < (dh+mTextHeight)) {
+ c.drawText(mText, x, y, mTextPaint);
+ x += deltaX;
+ if (x >= dw) {
+ x -= (dw+mTextWidth);
+ y += deltaY;
+ }
+ }
+ mSurface.unlockCanvasAndPost(c);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
similarity index 71%
rename from services/java/com/android/server/WindowManagerService.java
rename to services/java/com/android/server/wm/WindowManagerService.java
index b662c55..a598ce9 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -22,7 +22,6 @@
import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -42,6 +41,10 @@
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.WindowManagerPolicyThread;
+import com.android.server.AttributeCache;
+import com.android.server.EventLogTags;
+import com.android.server.PowerManagerService;
+import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import android.Manifest;
@@ -50,8 +53,6 @@
import android.app.StatusBarManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -59,17 +60,12 @@
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
-import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.Typeface;
-import android.graphics.Paint.FontMetricsInt;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
@@ -98,8 +94,6 @@
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Display;
-import android.view.DragEvent;
-import android.view.Gravity;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -116,13 +110,10 @@
import android.view.Surface;
import android.view.SurfaceSession;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
-import android.view.Surface.OutOfResourcesException;
import android.view.WindowManager.LayoutParams;
-import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
@@ -219,7 +210,7 @@
private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
// Default input dispatching timeout in nanoseconds.
- private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
+ static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
@@ -507,336 +498,8 @@
boolean mTurnOnScreen;
- /**
- * Drag/drop state
- */
- class DragState {
- IBinder mToken;
- Surface mSurface;
- int mFlags;
- IBinder mLocalWin;
- ClipData mData;
- ClipDescription mDataDescription;
- boolean mDragResult;
- float mCurrentX, mCurrentY;
- float mThumbOffsetX, mThumbOffsetY;
- InputChannel mServerChannel, mClientChannel;
- WindowState mTargetWindow;
- ArrayList<WindowState> mNotifiedWindows;
- boolean mDragInProgress;
-
- private final Region mTmpRegion = new Region();
-
- DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
- mToken = token;
- mSurface = surface;
- mFlags = flags;
- mLocalWin = localWin;
- mNotifiedWindows = new ArrayList<WindowState>();
- }
-
- void reset() {
- if (mSurface != null) {
- mSurface.destroy();
- }
- mSurface = null;
- mFlags = 0;
- mLocalWin = null;
- mToken = null;
- mData = null;
- mThumbOffsetX = mThumbOffsetY = 0;
- mNotifiedWindows = null;
- }
-
- void register() {
- if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
- if (mClientChannel != null) {
- Slog.e(TAG, "Duplicate register of drag input channel");
- } else {
- InputChannel[] channels = InputChannel.openInputChannelPair("drag");
- mServerChannel = channels[0];
- mClientChannel = channels[1];
- mInputManager.registerInputChannel(mServerChannel, null);
- InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
- mH.getLooper().getQueue());
- }
- }
-
- void unregister() {
- if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
- if (mClientChannel == null) {
- Slog.e(TAG, "Unregister of nonexistent drag input channel");
- } else {
- mInputManager.unregisterInputChannel(mServerChannel);
- InputQueue.unregisterInputChannel(mClientChannel);
- mClientChannel.dispose();
- mServerChannel.dispose();
- mClientChannel = null;
- mServerChannel = null;
- }
- }
-
- int getDragLayerLw() {
- return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- }
-
- /* call out to each visible window/session informing it about the drag
- */
- void broadcastDragStartedLw(final float touchX, final float touchY) {
- // Cache a base-class instance of the clip metadata so that parceling
- // works correctly in calling out to the apps.
- mDataDescription = (mData != null) ? mData.getDescription() : null;
- mNotifiedWindows.clear();
- mDragInProgress = true;
-
- if (DEBUG_DRAG) {
- Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
- }
-
- final int N = mWindows.size();
- for (int i = 0; i < N; i++) {
- sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
- }
- }
-
- /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
- * designated window is potentially a drop recipient. There are race situations
- * around DRAG_ENDED broadcast, so we make sure that once we've declared that
- * the drag has ended, we never send out another DRAG_STARTED for this drag action.
- *
- * This method clones the 'event' parameter if it's being delivered to the same
- * process, so it's safe for the caller to call recycle() on the event afterwards.
- */
- private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
- ClipDescription desc) {
- // Don't actually send the event if the drag is supposed to be pinned
- // to the originating window but 'newWin' is not that window.
- if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
- final IBinder winBinder = newWin.mClient.asBinder();
- if (winBinder != mLocalWin) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
- }
- return;
- }
- }
-
- if (mDragInProgress && newWin.isPotentialDragTarget()) {
- DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
- touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
- null, desc, null, false);
- try {
- newWin.mClient.dispatchDragEvent(event);
- // track each window that we've notified that the drag is starting
- mNotifiedWindows.add(newWin);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to drag-start window " + newWin);
- } finally {
- // if the callee was local, the dispatch has already recycled the event
- if (Process.myPid() != newWin.mSession.mPid) {
- event.recycle();
- }
- }
- }
- }
-
- /* helper - construct and send a DRAG_STARTED event only if the window has not
- * previously been notified, i.e. it became visible after the drag operation
- * was begun. This is a rare case.
- */
- private void sendDragStartedIfNeededLw(WindowState newWin) {
- if (mDragInProgress) {
- // If we have sent the drag-started, we needn't do so again
- for (WindowState ws : mNotifiedWindows) {
- if (ws == newWin) {
- return;
- }
- }
- if (DEBUG_DRAG) {
- Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
- }
- sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
- }
- }
-
- void broadcastDragEndedLw() {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "broadcasting DRAG_ENDED");
- }
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
- 0, 0, null, null, null, mDragResult);
- for (WindowState ws: mNotifiedWindows) {
- try {
- ws.mClient.dispatchDragEvent(evt);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to drag-end window " + ws);
- }
- }
- mNotifiedWindows.clear();
- mDragInProgress = false;
- evt.recycle();
- }
-
- void endDragLw() {
- mDragState.broadcastDragEndedLw();
-
- // stop intercepting input
- mDragState.unregister();
- mInputMonitor.updateInputWindowsLw(true /*force*/);
-
- // free our resources and drop all the object references
- mDragState.reset();
- mDragState = null;
-
- if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
- boolean changed = setRotationUncheckedLocked(
- WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
- if (changed) {
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- }
- }
-
- void notifyMoveLw(float x, float y) {
- final int myPid = Process.myPid();
-
- // Move the surface to the given touch
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
- Surface.openTransaction();
- try {
- mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
- + mSurface + ": pos=(" +
- (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
- }
-
- // Tell the affected window
- WindowState touchedWin = getTouchedWinAtPointLw(x, y);
- if (touchedWin == null) {
- if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
- return;
- }
- if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
- final IBinder touchedBinder = touchedWin.mClient.asBinder();
- if (touchedBinder != mLocalWin) {
- // This drag is pinned only to the originating window, but the drag
- // point is outside that window. Pretend it's over empty space.
- touchedWin = null;
- }
- }
- try {
- // have we dragged over a new window?
- if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
- }
- // force DRAG_EXITED_EVENT if appropriate
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
- x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
- null, null, null, false);
- mTargetWindow.mClient.dispatchDragEvent(evt);
- if (myPid != mTargetWindow.mSession.mPid) {
- evt.recycle();
- }
- }
- if (touchedWin != null) {
- if (false && DEBUG_DRAG) {
- Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
- }
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
- x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, null, null, false);
- touchedWin.mClient.dispatchDragEvent(evt);
- if (myPid != touchedWin.mSession.mPid) {
- evt.recycle();
- }
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "can't send drag notification to windows");
- }
- mTargetWindow = touchedWin;
- }
-
- // Tell the drop target about the data. Returns 'true' if we can immediately
- // dispatch the global drag-ended message, 'false' if we need to wait for a
- // result from the recipient.
- boolean notifyDropLw(float x, float y) {
- WindowState touchedWin = getTouchedWinAtPointLw(x, y);
- if (touchedWin == null) {
- // "drop" outside a valid window -- no recipient to apply a
- // timeout to, and we can send the drag-ended message immediately.
- mDragResult = false;
- return true;
- }
-
- if (DEBUG_DRAG) {
- Slog.d(TAG, "sending DROP to " + touchedWin);
- }
- final int myPid = Process.myPid();
- final IBinder token = touchedWin.mClient.asBinder();
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
- x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, null, mData, false);
- try {
- touchedWin.mClient.dispatchDragEvent(evt);
-
- // 5 second timeout for this window to respond to the drop
- mH.removeMessages(H.DRAG_END_TIMEOUT, token);
- Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
- mH.sendMessageDelayed(msg, 5000);
- } catch (RemoteException e) {
- Slog.w(TAG, "can't send drop notification to win " + touchedWin);
- return true;
- } finally {
- if (myPid != touchedWin.mSession.mPid) {
- evt.recycle();
- }
- }
- mToken = token;
- return false;
- }
-
- // Find the visible, touch-deliverable window under the given point
- private WindowState getTouchedWinAtPointLw(float xf, float yf) {
- WindowState touchedWin = null;
- final int x = (int) xf;
- final int y = (int) yf;
- final ArrayList<WindowState> windows = mWindows;
- final int N = windows.size();
- for (int i = N - 1; i >= 0; i--) {
- WindowState child = windows.get(i);
- final int flags = child.mAttrs.flags;
- if (!child.isVisibleLw()) {
- // not visible == don't tell about drags
- continue;
- }
- if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
- // not touchable == don't tell about drags
- continue;
- }
-
- child.getTouchableRegion(mTmpRegion);
-
- final int touchFlags = flags &
- (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
- if (mTmpRegion.contains(x, y) || touchFlags == 0) {
- // Found it
- touchedWin = child;
- break;
- }
- }
-
- return touchedWin;
- }
- }
-
DragState mDragState = null;
- private final InputHandler mDragInputHandler = new BaseInputHandler() {
+ final InputHandler mDragInputHandler = new BaseInputHandler() {
@Override
public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
boolean handled = false;
@@ -2300,7 +1963,7 @@
+ attrs.token + ". Aborting.");
return WindowManagerImpl.ADD_BAD_APP_TOKEN;
}
- token = new WindowToken(attrs.token, -1, false);
+ token = new WindowToken(this, attrs.token, -1, false);
addToken = true;
} else if (attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type <= LAST_APPLICATION_WINDOW) {
@@ -2334,7 +1997,7 @@
}
}
- win = new WindowState(session, client, token,
+ win = new WindowState(this, session, client, token,
attachedWindow, attrs, viewVisibility);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
@@ -2632,7 +2295,7 @@
mInputMonitor.updateInputWindowsLw(true /*force*/);
}
- private static void logSurface(WindowState w, String msg, RuntimeException where) {
+ static void logSurface(WindowState w, String msg, RuntimeException where) {
String str = " SURFACE " + Integer.toHexString(w.hashCode())
+ ": " + msg + " / " + w.mAttrs.getTitle();
if (where != null) {
@@ -2642,7 +2305,7 @@
}
}
- private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
+ void setTransparentRegionWindow(Session session, IWindow client, Region region) {
long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
@@ -3096,7 +2759,7 @@
return null;
}
- private void applyEnterAnimationLocked(WindowState win) {
+ void applyEnterAnimationLocked(WindowState win) {
int transit = WindowManagerPolicy.TRANSIT_SHOW;
if (win.mEnterAnimationPending) {
win.mEnterAnimationPending = false;
@@ -3106,7 +2769,7 @@
applyAnimationLocked(win, transit, true);
}
- private boolean applyAnimationLocked(WindowState win,
+ boolean applyAnimationLocked(WindowState win,
int transit, boolean isEntrance) {
if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
@@ -3362,7 +3025,7 @@
Slog.w(TAG, "Attempted to add existing input method token: " + token);
return;
}
- wtoken = new WindowToken(token, type, true);
+ wtoken = new WindowToken(this, token, type, true);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
mWallpaperTokens.add(wtoken);
@@ -3450,7 +3113,7 @@
Slog.w(TAG, "Attempted to add existing app token: " + token);
return;
}
- wtoken = new AppWindowToken(token);
+ wtoken = new AppWindowToken(this, token);
wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
wtoken.groupId = groupId;
wtoken.appFullscreen = fullscreen;
@@ -5347,8 +5010,8 @@
*
* @return True if the server was successfully started, false otherwise.
*
- * @see com.android.server.ViewServer
- * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
+ * @see com.android.server.wm.ViewServer
+ * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
*/
public boolean startViewServer(int port) {
if (isSystemSecure()) {
@@ -5394,7 +5057,7 @@
* @return True if the server stopped, false if it wasn't started or
* couldn't be stopped.
*
- * @see com.android.server.ViewServer
+ * @see com.android.server.wm.ViewServer
*/
public boolean stopViewServer() {
if (isSystemSecure()) {
@@ -5416,7 +5079,7 @@
*
* @return True if the server is running, false otherwise.
*
- * @see com.android.server.ViewServer
+ * @see com.android.server.wm.ViewServer
*/
public boolean isViewServerRunning() {
if (isSystemSecure()) {
@@ -5578,7 +5241,7 @@
parameters = "";
}
- final WindowManagerService.WindowState window = findWindow(hashCode);
+ final WindowState window = findWindow(hashCode);
if (window == null) {
return false;
}
@@ -5889,7 +5552,7 @@
outSurface.copyFrom(surface);
final IBinder winBinder = window.asBinder();
token = new Binder();
- mDragState = new DragState(token, surface, /*flags*/ 0, winBinder);
+ mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
mDragState.mSurface = surface;
token = mDragState.mToken = new Binder();
@@ -5919,355 +5582,8 @@
// Input Events and Focus Management
// -------------------------------------------------------------
- InputMonitor mInputMonitor = new InputMonitor();
+ final InputMonitor mInputMonitor = new InputMonitor(this);
- /* Tracks the progress of input dispatch and ensures that input dispatch state
- * is kept in sync with changes in window focus, visibility, registration, and
- * other relevant Window Manager state transitions. */
- final class InputMonitor {
- // Current window with input focus for keys and other non-touch events. May be null.
- private WindowState mInputFocus;
-
- // When true, prevents input dispatch from proceeding until set to false again.
- private boolean mInputDispatchFrozen;
-
- // When true, input dispatch proceeds normally. Otherwise all events are dropped.
- private boolean mInputDispatchEnabled = true;
-
- // When true, need to call updateInputWindowsLw().
- private boolean mUpdateInputWindowsNeeded = true;
-
- // Temporary list of windows information to provide to the input dispatcher.
- private InputWindowList mTempInputWindows = new InputWindowList();
-
- // Temporary input application object to provide to the input dispatcher.
- private InputApplication mTempInputApplication = new InputApplication();
-
- // Set to true when the first input device configuration change notification
- // is received to indicate that the input devices are ready.
- private final Object mInputDevicesReadyMonitor = new Object();
- private boolean mInputDevicesReady;
-
- /* Notifies the window manager about a broken input channel.
- *
- * Called by the InputManager.
- */
- public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
- if (inputWindowHandle == null) {
- return;
- }
-
- synchronized (mWindowMap) {
- WindowState windowState = (WindowState) inputWindowHandle.windowState;
- Slog.i(TAG, "WINDOW DIED " + windowState);
- removeWindowLocked(windowState.mSession, windowState);
- }
- }
-
- /* Notifies the window manager about an application that is not responding.
- * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
- *
- * Called by the InputManager.
- */
- public long notifyANR(InputApplicationHandle inputApplicationHandle,
- InputWindowHandle inputWindowHandle) {
- AppWindowToken appWindowToken = null;
- if (inputWindowHandle != null) {
- synchronized (mWindowMap) {
- WindowState windowState = (WindowState) inputWindowHandle.windowState;
- if (windowState != null) {
- Slog.i(TAG, "Input event dispatching timed out sending to "
- + windowState.mAttrs.getTitle());
- appWindowToken = windowState.mAppToken;
- }
- }
- }
-
- if (appWindowToken == null && inputApplicationHandle != null) {
- appWindowToken = inputApplicationHandle.appWindowToken;
- Slog.i(TAG, "Input event dispatching timed out sending to application "
- + appWindowToken.stringName);
- }
-
- if (appWindowToken != null && appWindowToken.appToken != null) {
- try {
- // Notify the activity manager about the timeout and let it decide whether
- // to abort dispatching or keep waiting.
- boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
- if (! abort) {
- // The activity manager declined to abort dispatching.
- // Wait a bit longer and timeout again later.
- return appWindowToken.inputDispatchingTimeoutNanos;
- }
- } catch (RemoteException ex) {
- }
- }
- return 0; // abort dispatching
- }
-
- private void addDragInputWindowLw(InputWindowList windowList) {
- final InputWindow inputWindow = windowList.add();
- inputWindow.inputChannel = mDragState.mServerChannel;
- inputWindow.name = "drag";
- inputWindow.layoutParamsFlags = 0;
- inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
- inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- inputWindow.visible = true;
- inputWindow.canReceiveKeys = false;
- inputWindow.hasFocus = true;
- inputWindow.hasWallpaper = false;
- inputWindow.paused = false;
- inputWindow.layer = mDragState.getDragLayerLw();
- inputWindow.ownerPid = Process.myPid();
- inputWindow.ownerUid = Process.myUid();
-
- // The drag window covers the entire display
- inputWindow.frameLeft = 0;
- inputWindow.frameTop = 0;
- inputWindow.frameRight = mDisplay.getWidth();
- inputWindow.frameBottom = mDisplay.getHeight();
-
- // The drag window cannot receive new touches.
- inputWindow.touchableRegion.setEmpty();
- }
-
- public void setUpdateInputWindowsNeededLw() {
- mUpdateInputWindowsNeeded = true;
- }
-
- /* Updates the cached window information provided to the input dispatcher. */
- public void updateInputWindowsLw(boolean force) {
- if (!force && !mUpdateInputWindowsNeeded) {
- return;
- }
- mUpdateInputWindowsNeeded = false;
-
- // Populate the input window list with information about all of the windows that
- // could potentially receive input.
- // As an optimization, we could try to prune the list of windows but this turns
- // out to be difficult because only the native code knows for sure which window
- // currently has touch focus.
- final ArrayList<WindowState> windows = mWindows;
-
- // If there's a drag in flight, provide a pseudowindow to catch drag input
- final boolean inDrag = (mDragState != null);
- if (inDrag) {
- if (DEBUG_DRAG) {
- Log.d(TAG, "Inserting drag window");
- }
- addDragInputWindowLw(mTempInputWindows);
- }
-
- final int N = windows.size();
- for (int i = N - 1; i >= 0; i--) {
- final WindowState child = windows.get(i);
- if (child.mInputChannel == null || child.mRemoved) {
- // Skip this window because it cannot possibly receive input.
- continue;
- }
-
- final int flags = child.mAttrs.flags;
- final int type = child.mAttrs.type;
-
- final boolean hasFocus = (child == mInputFocus);
- final boolean isVisible = child.isVisibleLw();
- final boolean hasWallpaper = (child == mWallpaperTarget)
- && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
-
- // If there's a drag in progress and 'child' is a potential drop target,
- // make sure it's been told about the drag
- if (inDrag && isVisible) {
- mDragState.sendDragStartedIfNeededLw(child);
- }
-
- // Add a window to our list of input windows.
- final InputWindow inputWindow = mTempInputWindows.add();
- inputWindow.inputWindowHandle = child.mInputWindowHandle;
- inputWindow.inputChannel = child.mInputChannel;
- inputWindow.name = child.toString();
- inputWindow.layoutParamsFlags = flags;
- inputWindow.layoutParamsType = type;
- inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
- inputWindow.visible = isVisible;
- inputWindow.canReceiveKeys = child.canReceiveKeys();
- inputWindow.hasFocus = hasFocus;
- inputWindow.hasWallpaper = hasWallpaper;
- inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
- inputWindow.layer = child.mLayer;
- inputWindow.ownerPid = child.mSession.mPid;
- inputWindow.ownerUid = child.mSession.mUid;
-
- final Rect frame = child.mFrame;
- inputWindow.frameLeft = frame.left;
- inputWindow.frameTop = frame.top;
- inputWindow.frameRight = frame.right;
- inputWindow.frameBottom = frame.bottom;
-
- child.getTouchableRegion(inputWindow.touchableRegion);
- }
-
- // Send windows to native code.
- mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
-
- // Clear the list in preparation for the next round.
- // Also avoids keeping InputChannel objects referenced unnecessarily.
- mTempInputWindows.clear();
- }
-
- /* Notifies that the input device configuration has changed. */
- public void notifyConfigurationChanged() {
- sendNewConfiguration();
-
- synchronized (mInputDevicesReadyMonitor) {
- if (!mInputDevicesReady) {
- mInputDevicesReady = true;
- mInputDevicesReadyMonitor.notifyAll();
- }
- }
- }
-
- /* Waits until the built-in input devices have been configured. */
- public boolean waitForInputDevicesReady(long timeoutMillis) {
- synchronized (mInputDevicesReadyMonitor) {
- if (!mInputDevicesReady) {
- try {
- mInputDevicesReadyMonitor.wait(timeoutMillis);
- } catch (InterruptedException ex) {
- }
- }
- return mInputDevicesReady;
- }
- }
-
- /* Notifies that the lid switch changed state. */
- public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
- mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
- }
-
- /* Provides an opportunity for the window manager policy to intercept early key
- * processing as soon as the key has been read from the device. */
- public int interceptKeyBeforeQueueing(
- KeyEvent event, int policyFlags, boolean isScreenOn) {
- return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
- }
-
- /* Provides an opportunity for the window manager policy to process a key before
- * ordinary dispatch. */
- public boolean interceptKeyBeforeDispatching(
- InputWindowHandle focus, KeyEvent event, int policyFlags) {
- WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
- return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
- }
-
- /* Provides an opportunity for the window manager policy to process a key that
- * the application did not handle. */
- public KeyEvent dispatchUnhandledKey(
- InputWindowHandle focus, KeyEvent event, int policyFlags) {
- WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
- return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
- }
-
- /* Called when the current input focus changes.
- * Layer assignment is assumed to be complete by the time this is called.
- */
- public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
- if (DEBUG_INPUT) {
- Slog.d(TAG, "Input focus has changed to " + newWindow);
- }
-
- if (newWindow != mInputFocus) {
- if (newWindow != null && newWindow.canReceiveKeys()) {
- // Displaying a window implicitly causes dispatching to be unpaused.
- // This is to protect against bugs if someone pauses dispatching but
- // forgets to resume.
- newWindow.mToken.paused = false;
- }
-
- mInputFocus = newWindow;
- setUpdateInputWindowsNeededLw();
-
- if (updateInputWindows) {
- updateInputWindowsLw(false /*force*/);
- }
- }
- }
-
- public void setFocusedAppLw(AppWindowToken newApp) {
- // Focused app has changed.
- if (newApp == null) {
- mInputManager.setFocusedApplication(null);
- } else {
- mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
- mTempInputApplication.name = newApp.toString();
- mTempInputApplication.dispatchingTimeoutNanos =
- newApp.inputDispatchingTimeoutNanos;
-
- mInputManager.setFocusedApplication(mTempInputApplication);
-
- mTempInputApplication.recycle();
- }
- }
-
- public void pauseDispatchingLw(WindowToken window) {
- if (! window.paused) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Pausing WindowToken " + window);
- }
-
- window.paused = true;
- updateInputWindowsLw(true /*force*/);
- }
- }
-
- public void resumeDispatchingLw(WindowToken window) {
- if (window.paused) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Resuming WindowToken " + window);
- }
-
- window.paused = false;
- updateInputWindowsLw(true /*force*/);
- }
- }
-
- public void freezeInputDispatchingLw() {
- if (! mInputDispatchFrozen) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Freezing input dispatching");
- }
-
- mInputDispatchFrozen = true;
- updateInputDispatchModeLw();
- }
- }
-
- public void thawInputDispatchingLw() {
- if (mInputDispatchFrozen) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Thawing input dispatching");
- }
-
- mInputDispatchFrozen = false;
- updateInputDispatchModeLw();
- }
- }
-
- public void setEventDispatchingLw(boolean enabled) {
- if (mInputDispatchEnabled != enabled) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Setting event dispatching to " + enabled);
- }
-
- mInputDispatchEnabled = enabled;
- updateInputDispatchModeLw();
- }
- }
-
- private void updateInputDispatchModeLw() {
- mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
- }
- }
-
public void pauseKeyDispatching(IBinder _token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"pauseKeyDispatching()")) {
@@ -6496,2409 +5812,6 @@
mPolicy.systemReady();
}
- // -------------------------------------------------------------
- // Client Session State
- // -------------------------------------------------------------
-
- private final class Session extends IWindowSession.Stub
- implements IBinder.DeathRecipient {
- final IInputMethodClient mClient;
- final IInputContext mInputContext;
- final int mUid;
- final int mPid;
- final String mStringName;
- SurfaceSession mSurfaceSession;
- int mNumWindow = 0;
- boolean mClientDead = false;
-
- public Session(IInputMethodClient client, IInputContext inputContext) {
- mClient = client;
- mInputContext = inputContext;
- mUid = Binder.getCallingUid();
- mPid = Binder.getCallingPid();
- StringBuilder sb = new StringBuilder();
- sb.append("Session{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" uid ");
- sb.append(mUid);
- sb.append("}");
- mStringName = sb.toString();
-
- synchronized (mWindowMap) {
- if (mInputMethodManager == null && mHaveInputMethods) {
- IBinder b = ServiceManager.getService(
- Context.INPUT_METHOD_SERVICE);
- mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
- }
- }
- long ident = Binder.clearCallingIdentity();
- try {
- // Note: it is safe to call in to the input method manager
- // here because we are not holding our lock.
- if (mInputMethodManager != null) {
- mInputMethodManager.addClient(client, inputContext,
- mUid, mPid);
- } else {
- client.setUsingInputMethod(false);
- }
- client.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- // The caller has died, so we can just forget about this.
- try {
- if (mInputMethodManager != null) {
- mInputMethodManager.removeClient(client);
- }
- } catch (RemoteException ee) {
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- return super.onTransact(code, data, reply, flags);
- } catch (RuntimeException e) {
- // Log all 'real' exceptions thrown to the caller
- if (!(e instanceof SecurityException)) {
- Slog.e(TAG, "Window Session Crash", e);
- }
- throw e;
- }
- }
-
- public void binderDied() {
- // Note: it is safe to call in to the input method manager
- // here because we are not holding our lock.
- try {
- if (mInputMethodManager != null) {
- mInputMethodManager.removeClient(mClient);
- }
- } catch (RemoteException e) {
- }
- synchronized(mWindowMap) {
- mClient.asBinder().unlinkToDeath(this, 0);
- mClientDead = true;
- killSessionLocked();
- }
- }
-
- public int add(IWindow window, WindowManager.LayoutParams attrs,
- int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
- return addWindow(this, window, attrs, viewVisibility, outContentInsets,
- outInputChannel);
- }
-
- public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
- int viewVisibility, Rect outContentInsets) {
- return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
- }
-
- public void remove(IWindow window) {
- removeWindow(this, window);
- }
-
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
- int requestedWidth, int requestedHeight, int viewFlags,
- boolean insetsPending, Rect outFrame, Rect outContentInsets,
- Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
- //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
- int res = relayoutWindow(this, window, attrs,
- requestedWidth, requestedHeight, viewFlags, insetsPending,
- outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
- //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
- return res;
- }
-
- public void setTransparentRegion(IWindow window, Region region) {
- setTransparentRegionWindow(this, window, region);
- }
-
- public void setInsets(IWindow window, int touchableInsets,
- Rect contentInsets, Rect visibleInsets, Region touchableArea) {
- setInsetsWindow(this, window, touchableInsets, contentInsets,
- visibleInsets, touchableArea);
- }
-
- public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
- getWindowDisplayFrame(this, window, outDisplayFrame);
- }
-
- public void finishDrawing(IWindow window) {
- if (localLOGV) Slog.v(
- TAG, "IWindow finishDrawing called for " + window);
- finishDrawingWindow(this, window);
- }
-
- public void setInTouchMode(boolean mode) {
- synchronized(mWindowMap) {
- mInTouchMode = mode;
- }
- }
-
- public boolean getInTouchMode() {
- synchronized(mWindowMap) {
- return mInTouchMode;
- }
- }
-
- public boolean performHapticFeedback(IWindow window, int effectId,
- boolean always) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- return mPolicy.performHapticFeedbackLw(
- windowForClientLocked(this, window, true),
- effectId, always);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- /* Drag/drop */
- public IBinder prepareDrag(IWindow window, int flags,
- int width, int height, Surface outSurface) {
- return prepareDragSurface(window, mSurfaceSession, flags,
- width, height, outSurface);
- }
-
- public boolean performDrag(IWindow window, IBinder dragToken,
- float touchX, float touchY, float thumbCenterX, float thumbCenterY,
- ClipData data) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
- }
-
- synchronized (mWindowMap) {
- if (mDragState == null) {
- Slog.w(TAG, "No drag prepared");
- throw new IllegalStateException("performDrag() without prepareDrag()");
- }
-
- if (dragToken != mDragState.mToken) {
- Slog.w(TAG, "Performing mismatched drag");
- throw new IllegalStateException("performDrag() does not match prepareDrag()");
- }
-
- WindowState callingWin = windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG, "Bad requesting window " + window);
- return false; // !!! TODO: throw here?
- }
-
- // !!! TODO: if input is not still focused on the initiating window, fail
- // the drag initiation (e.g. an alarm window popped up just as the application
- // called performDrag()
-
- mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
-
- // !!! TODO: extract the current touch (x, y) in screen coordinates. That
- // will let us eliminate the (touchX,touchY) parameters from the API.
-
- // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
- // the actual drag event dispatch stuff in the dragstate
-
- mDragState.register();
- mInputMonitor.updateInputWindowsLw(true /*force*/);
- if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
- mDragState.mServerChannel)) {
- Slog.e(TAG, "Unable to transfer touch focus");
- mDragState.unregister();
- mDragState = null;
- mInputMonitor.updateInputWindowsLw(true /*force*/);
- return false;
- }
-
- mDragState.mData = data;
- mDragState.mCurrentX = touchX;
- mDragState.mCurrentY = touchY;
- mDragState.broadcastDragStartedLw(touchX, touchY);
-
- // remember the thumb offsets for later
- mDragState.mThumbOffsetX = thumbCenterX;
- mDragState.mThumbOffsetY = thumbCenterY;
-
- // Make the surface visible at the proper location
- final Surface surface = mDragState.mSurface;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performDrag");
- Surface.openTransaction();
- try {
- surface.setPosition((int)(touchX - thumbCenterX),
- (int)(touchY - thumbCenterY));
- surface.setAlpha(.7071f);
- surface.setLayer(mDragState.getDragLayerLw());
- surface.show();
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performDrag");
- }
- }
-
- return true; // success!
- }
-
- public void reportDropResult(IWindow window, boolean consumed) {
- IBinder token = window.asBinder();
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
- }
-
- synchronized (mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (mDragState == null || mDragState.mToken != token) {
- Slog.w(TAG, "Invalid drop-result claim by " + window);
- throw new IllegalStateException("reportDropResult() by non-recipient");
- }
-
- // The right window has responded, even if it's no longer around,
- // so be sure to halt the timeout even if the later WindowState
- // lookup fails.
- mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
- WindowState callingWin = windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG, "Bad result-reporting window " + window);
- return; // !!! TODO: throw here?
- }
-
- mDragState.mDragResult = consumed;
- mDragState.endDragLw();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void dragRecipientEntered(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
- }
- }
-
- public void dragRecipientExited(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
- }
- }
-
- public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- setWindowWallpaperPositionLocked(
- windowForClientLocked(this, window, true),
- x, y, xStep, yStep);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void wallpaperOffsetsComplete(IBinder window) {
- WindowManagerService.this.wallpaperOffsetsComplete(window);
- }
-
- public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
- int z, Bundle extras, boolean sync) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- return sendWindowWallpaperCommandLocked(
- windowForClientLocked(this, window, true),
- action, x, y, z, extras, sync);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void wallpaperCommandComplete(IBinder window, Bundle result) {
- WindowManagerService.this.wallpaperCommandComplete(window, result);
- }
-
- void windowAddedLocked() {
- if (mSurfaceSession == null) {
- if (localLOGV) Slog.v(
- TAG, "First window added to " + this + ", creating SurfaceSession");
- mSurfaceSession = new SurfaceSession();
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " NEW SURFACE SESSION " + mSurfaceSession);
- mSessions.add(this);
- }
- mNumWindow++;
- }
-
- void windowRemovedLocked() {
- mNumWindow--;
- killSessionLocked();
- }
-
- void killSessionLocked() {
- if (mNumWindow <= 0 && mClientDead) {
- mSessions.remove(this);
- if (mSurfaceSession != null) {
- if (localLOGV) Slog.v(
- TAG, "Last window removed from " + this
- + ", destroying " + mSurfaceSession);
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " KILL SURFACE SESSION " + mSurfaceSession);
- try {
- mSurfaceSession.kill();
- } catch (Exception e) {
- Slog.w(TAG, "Exception thrown when killing surface session "
- + mSurfaceSession + " in session " + this
- + ": " + e.toString());
- }
- mSurfaceSession = null;
- }
- }
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
- pw.print(" mClientDead="); pw.print(mClientDead);
- pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
- }
-
- @Override
- public String toString() {
- return mStringName;
- }
- }
-
- // -------------------------------------------------------------
- // Client Window State
- // -------------------------------------------------------------
-
- private final class WindowState implements WindowManagerPolicy.WindowState {
- final Session mSession;
- final IWindow mClient;
- WindowToken mToken;
- WindowToken mRootToken;
- AppWindowToken mAppToken;
- AppWindowToken mTargetAppToken;
- final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
- final DeathRecipient mDeathRecipient;
- final WindowState mAttachedWindow;
- final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
- final int mBaseLayer;
- final int mSubLayer;
- final boolean mLayoutAttached;
- final boolean mIsImWindow;
- final boolean mIsWallpaper;
- final boolean mIsFloatingLayer;
- int mViewVisibility;
- boolean mPolicyVisibility = true;
- boolean mPolicyVisibilityAfterAnim = true;
- boolean mAppFreezing;
- Surface mSurface;
- boolean mReportDestroySurface;
- boolean mSurfacePendingDestroy;
- boolean mAttachedHidden; // is our parent window hidden?
- boolean mLastHidden; // was this window last hidden?
- boolean mWallpaperVisible; // for wallpaper, what was last vis report?
- int mRequestedWidth;
- int mRequestedHeight;
- int mLastRequestedWidth;
- int mLastRequestedHeight;
- int mLayer;
- int mAnimLayer;
- int mLastLayer;
- boolean mHaveFrame;
- boolean mObscured;
- boolean mTurnOnScreen;
-
- int mLayoutSeq = -1;
-
- Configuration mConfiguration = null;
-
- // Actual frame shown on-screen (may be modified by animation)
- final Rect mShownFrame = new Rect();
- final Rect mLastShownFrame = new Rect();
-
- /**
- * Set when we have changed the size of the surface, to know that
- * we must tell them application to resize (and thus redraw itself).
- */
- boolean mSurfaceResized;
-
- /**
- * Insets that determine the actually visible area
- */
- final Rect mVisibleInsets = new Rect();
- final Rect mLastVisibleInsets = new Rect();
- boolean mVisibleInsetsChanged;
-
- /**
- * Insets that are covered by system windows
- */
- final Rect mContentInsets = new Rect();
- final Rect mLastContentInsets = new Rect();
- boolean mContentInsetsChanged;
-
- /**
- * Set to true if we are waiting for this window to receive its
- * given internal insets before laying out other windows based on it.
- */
- boolean mGivenInsetsPending;
-
- /**
- * These are the content insets that were given during layout for
- * this window, to be applied to windows behind it.
- */
- final Rect mGivenContentInsets = new Rect();
-
- /**
- * These are the visible insets that were given during layout for
- * this window, to be applied to windows behind it.
- */
- final Rect mGivenVisibleInsets = new Rect();
-
- /**
- * This is the given touchable area relative to the window frame, or null if none.
- */
- final Region mGivenTouchableRegion = new Region();
-
- /**
- * Flag indicating whether the touchable region should be adjusted by
- * the visible insets; if false the area outside the visible insets is
- * NOT touchable, so we must use those to adjust the frame during hit
- * tests.
- */
- int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
-
- // Current transformation being applied.
- boolean mHaveMatrix;
- float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
- float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
- float mHScale=1, mVScale=1;
- float mLastHScale=1, mLastVScale=1;
- final Matrix mTmpMatrix = new Matrix();
-
- // "Real" frame that the application sees.
- final Rect mFrame = new Rect();
- final Rect mLastFrame = new Rect();
-
- final Rect mContainingFrame = new Rect();
- final Rect mDisplayFrame = new Rect();
- final Rect mContentFrame = new Rect();
- final Rect mParentFrame = new Rect();
- final Rect mVisibleFrame = new Rect();
-
- boolean mContentChanged;
-
- float mShownAlpha = 1;
- float mAlpha = 1;
- float mLastAlpha = 1;
-
- // Set to true if, when the window gets displayed, it should perform
- // an enter animation.
- boolean mEnterAnimationPending;
-
- // Currently running animation.
- boolean mAnimating;
- boolean mLocalAnimating;
- Animation mAnimation;
- boolean mAnimationIsEntrance;
- boolean mHasTransformation;
- boolean mHasLocalTransformation;
- final Transformation mTransformation = new Transformation();
-
- // If a window showing a wallpaper: the requested offset for the
- // wallpaper; if a wallpaper window: the currently applied offset.
- float mWallpaperX = -1;
- float mWallpaperY = -1;
-
- // If a window showing a wallpaper: what fraction of the offset
- // range corresponds to a full virtual screen.
- float mWallpaperXStep = -1;
- float mWallpaperYStep = -1;
-
- // Wallpaper windows: pixels offset based on above variables.
- int mXOffset;
- int mYOffset;
-
- // This is set after IWindowSession.relayout() has been called at
- // least once for the window. It allows us to detect the situation
- // where we don't yet have a surface, but should have one soon, so
- // we can give the window focus before waiting for the relayout.
- boolean mRelayoutCalled;
-
- // This is set after the Surface has been created but before the
- // window has been drawn. During this time the surface is hidden.
- boolean mDrawPending;
-
- // This is set after the window has finished drawing for the first
- // time but before its surface is shown. The surface will be
- // displayed when the next layout is run.
- boolean mCommitDrawPending;
-
- // This is set during the time after the window's drawing has been
- // committed, and before its surface is actually shown. It is used
- // to delay showing the surface until all windows in a token are ready
- // to be shown.
- boolean mReadyToShow;
-
- // Set when the window has been shown in the screen the first time.
- boolean mHasDrawn;
-
- // Currently running an exit animation?
- boolean mExiting;
-
- // Currently on the mDestroySurface list?
- boolean mDestroying;
-
- // Completely remove from window manager after exit animation?
- boolean mRemoveOnExit;
-
- // Set when the orientation is changing and this window has not yet
- // been updated for the new orientation.
- boolean mOrientationChanging;
-
- // Is this window now (or just being) removed?
- boolean mRemoved;
-
- // Temp for keeping track of windows that have been removed when
- // rebuilding window list.
- boolean mRebuilding;
-
- // For debugging, this is the last information given to the surface flinger.
- boolean mSurfaceShown;
- int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
- int mSurfaceLayer;
- float mSurfaceAlpha;
-
- // Input channel and input window handle used by the input dispatcher.
- InputWindowHandle mInputWindowHandle;
- InputChannel mInputChannel;
-
- // Used to improve performance of toString()
- String mStringNameCache;
- CharSequence mLastTitle;
- boolean mWasPaused;
-
- WindowState(Session s, IWindow c, WindowToken token,
- WindowState attachedWindow, WindowManager.LayoutParams a,
- int viewVisibility) {
- mSession = s;
- mClient = c;
- mToken = token;
- mAttrs.copyFrom(a);
- mViewVisibility = viewVisibility;
- DeathRecipient deathRecipient = new DeathRecipient();
- mAlpha = a.alpha;
- if (localLOGV) Slog.v(
- TAG, "Window " + this + " client=" + c.asBinder()
- + " token=" + token + " (" + mAttrs.token + ")");
- try {
- c.asBinder().linkToDeath(deathRecipient, 0);
- } catch (RemoteException e) {
- mDeathRecipient = null;
- mAttachedWindow = null;
- mLayoutAttached = false;
- mIsImWindow = false;
- mIsWallpaper = false;
- mIsFloatingLayer = false;
- mBaseLayer = 0;
- mSubLayer = 0;
- return;
- }
- mDeathRecipient = deathRecipient;
-
- if ((mAttrs.type >= FIRST_SUB_WINDOW &&
- mAttrs.type <= LAST_SUB_WINDOW)) {
- // The multiplier here is to reserve space for multiple
- // windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(
- attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
- mAttachedWindow = attachedWindow;
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
- mAttachedWindow.mChildWindows.add(this);
- mLayoutAttached = mAttrs.type !=
- WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
- || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
- mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
- mIsFloatingLayer = mIsImWindow || mIsWallpaper;
- } else {
- // The multiplier here is to reserve space for multiple
- // windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- mSubLayer = 0;
- mAttachedWindow = null;
- mLayoutAttached = false;
- mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
- || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
- mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
- mIsFloatingLayer = mIsImWindow || mIsWallpaper;
- }
-
- WindowState appWin = this;
- while (appWin.mAttachedWindow != null) {
- appWin = mAttachedWindow;
- }
- WindowToken appToken = appWin.mToken;
- while (appToken.appWindowToken == null) {
- WindowToken parent = mTokenMap.get(appToken.token);
- if (parent == null || appToken == parent) {
- break;
- }
- appToken = parent;
- }
- mRootToken = appToken;
- mAppToken = appToken.appWindowToken;
-
- mSurface = null;
- mRequestedWidth = 0;
- mRequestedHeight = 0;
- mLastRequestedWidth = 0;
- mLastRequestedHeight = 0;
- mXOffset = 0;
- mYOffset = 0;
- mLayer = 0;
- mAnimLayer = 0;
- mLastLayer = 0;
- mInputWindowHandle = new InputWindowHandle(
- mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
- }
-
- void attach() {
- if (localLOGV) Slog.v(
- TAG, "Attaching " + this + " token=" + mToken
- + ", list=" + mToken.windows);
- mSession.windowAddedLocked();
- }
-
- public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
- mHaveFrame = true;
-
- final Rect container = mContainingFrame;
- container.set(pf);
-
- final Rect display = mDisplayFrame;
- display.set(df);
-
- if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
- container.intersect(mCompatibleScreenFrame);
- if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
- display.intersect(mCompatibleScreenFrame);
- }
- }
-
- final int pw = container.right - container.left;
- final int ph = container.bottom - container.top;
-
- int w,h;
- if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
- w = mAttrs.width < 0 ? pw : mAttrs.width;
- h = mAttrs.height< 0 ? ph : mAttrs.height;
- } else {
- w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
- h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
- }
-
- if (!mParentFrame.equals(pf)) {
- //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
- // + " to " + pf);
- mParentFrame.set(pf);
- mContentChanged = true;
- }
-
- final Rect content = mContentFrame;
- content.set(cf);
-
- final Rect visible = mVisibleFrame;
- visible.set(vf);
-
- final Rect frame = mFrame;
- final int fw = frame.width();
- final int fh = frame.height();
-
- //System.out.println("In: w=" + w + " h=" + h + " container=" +
- // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
-
- Gravity.apply(mAttrs.gravity, w, h, container,
- (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
- (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
-
- //System.out.println("Out: " + mFrame);
-
- // Now make sure the window fits in the overall display.
- Gravity.applyDisplay(mAttrs.gravity, df, frame);
-
- // Make sure the content and visible frames are inside of the
- // final window frame.
- if (content.left < frame.left) content.left = frame.left;
- if (content.top < frame.top) content.top = frame.top;
- if (content.right > frame.right) content.right = frame.right;
- if (content.bottom > frame.bottom) content.bottom = frame.bottom;
- if (visible.left < frame.left) visible.left = frame.left;
- if (visible.top < frame.top) visible.top = frame.top;
- if (visible.right > frame.right) visible.right = frame.right;
- if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
-
- final Rect contentInsets = mContentInsets;
- contentInsets.left = content.left-frame.left;
- contentInsets.top = content.top-frame.top;
- contentInsets.right = frame.right-content.right;
- contentInsets.bottom = frame.bottom-content.bottom;
-
- final Rect visibleInsets = mVisibleInsets;
- visibleInsets.left = visible.left-frame.left;
- visibleInsets.top = visible.top-frame.top;
- visibleInsets.right = frame.right-visible.right;
- visibleInsets.bottom = frame.bottom-visible.bottom;
-
- if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
- updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
- mDisplay.getHeight(), false);
- }
-
- if (localLOGV) {
- //if ("com.google.android.youtube".equals(mAttrs.packageName)
- // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
- Slog.v(TAG, "Resolving (mRequestedWidth="
- + mRequestedWidth + ", mRequestedheight="
- + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
- + "): frame=" + mFrame.toShortString()
- + " ci=" + contentInsets.toShortString()
- + " vi=" + visibleInsets.toShortString());
- //}
- }
- }
-
- public Rect getFrameLw() {
- return mFrame;
- }
-
- public Rect getShownFrameLw() {
- return mShownFrame;
- }
-
- public Rect getDisplayFrameLw() {
- return mDisplayFrame;
- }
-
- public Rect getContentFrameLw() {
- return mContentFrame;
- }
-
- public Rect getVisibleFrameLw() {
- return mVisibleFrame;
- }
-
- public boolean getGivenInsetsPendingLw() {
- return mGivenInsetsPending;
- }
-
- public Rect getGivenContentInsetsLw() {
- return mGivenContentInsets;
- }
-
- public Rect getGivenVisibleInsetsLw() {
- return mGivenVisibleInsets;
- }
-
- public WindowManager.LayoutParams getAttrs() {
- return mAttrs;
- }
-
- public int getSurfaceLayer() {
- return mLayer;
- }
-
- public IApplicationToken getAppToken() {
- return mAppToken != null ? mAppToken.appToken : null;
- }
-
- public long getInputDispatchingTimeoutNanos() {
- return mAppToken != null
- ? mAppToken.inputDispatchingTimeoutNanos
- : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- }
-
- public boolean hasAppShownWindows() {
- return mAppToken != null ? mAppToken.firstWindowDrawn : false;
- }
-
- public void setAnimation(Animation anim) {
- if (localLOGV) Slog.v(
- TAG, "Setting animation in " + this + ": " + anim);
- mAnimating = false;
- mLocalAnimating = false;
- mAnimation = anim;
- mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
- mAnimation.scaleCurrentDuration(mWindowAnimationScale);
- }
-
- public void clearAnimation() {
- if (mAnimation != null) {
- mAnimating = true;
- mLocalAnimating = false;
- mAnimation.cancel();
- mAnimation = null;
- }
- }
-
- Surface createSurfaceLocked() {
- if (mSurface == null) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = false;
- mDrawPending = true;
- mCommitDrawPending = false;
- mReadyToShow = false;
- if (mAppToken != null) {
- mAppToken.allDrawn = false;
- }
-
- int flags = 0;
-
- if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- flags |= Surface.SECURE;
- }
- if (DEBUG_VISIBILITY) Slog.v(
- TAG, "Creating surface in session "
- + mSession.mSurfaceSession + " window " + this
- + " w=" + mFrame.width()
- + " h=" + mFrame.height() + " format="
- + mAttrs.format + " flags=" + flags);
-
- int w = mFrame.width();
- int h = mFrame.height();
- if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
- // for a scaled surface, we always want the requested
- // size.
- w = mRequestedWidth;
- h = mRequestedHeight;
- }
-
- // Something is wrong and SurfaceFlinger will not like this,
- // try to revert to sane values
- if (w <= 0) w = 1;
- if (h <= 0) h = 1;
-
- mSurfaceShown = false;
- mSurfaceLayer = 0;
- mSurfaceAlpha = 1;
- mSurfaceX = 0;
- mSurfaceY = 0;
- mSurfaceW = w;
- mSurfaceH = h;
- try {
- final boolean isHwAccelerated = (mAttrs.flags &
- WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
- final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
- if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
- flags |= Surface.OPAQUE;
- }
- mSurface = new Surface(
- mSession.mSurfaceSession, mSession.mPid,
- mAttrs.getTitle().toString(),
- 0, w, h, format, flags);
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
- + mSurface + " IN SESSION "
- + mSession.mSurfaceSession
- + ": pid=" + mSession.mPid + " format="
- + mAttrs.format + " flags=0x"
- + Integer.toHexString(flags)
- + " / " + this);
- } catch (Surface.OutOfResourcesException e) {
- Slog.w(TAG, "OutOfResourcesException creating surface");
- reclaimSomeSurfaceMemoryLocked(this, "create");
- return null;
- } catch (Exception e) {
- Slog.e(TAG, "Exception creating surface", e);
- return null;
- }
-
- if (localLOGV) Slog.v(
- TAG, "Got surface: " + mSurface
- + ", set left=" + mFrame.left + " top=" + mFrame.top
- + ", animLayer=" + mAnimLayer);
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
- logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
- mFrame.width() + "x" + mFrame.height() + "), layer=" +
- mAnimLayer + " HIDE", null);
- }
- Surface.openTransaction();
- try {
- try {
- mSurfaceX = mFrame.left + mXOffset;
- mSurfaceY = mFrame.top + mYOffset;
- mSurface.setPosition(mSurfaceX, mSurfaceY);
- mSurfaceLayer = mAnimLayer;
- mSurface.setLayer(mAnimLayer);
- mSurfaceShown = false;
- mSurface.hide();
- if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
- if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
- mSurface.setFlags(Surface.SURFACE_DITHER,
- Surface.SURFACE_DITHER);
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error creating surface in " + w, e);
- reclaimSomeSurfaceMemoryLocked(this, "create-init");
- }
- mLastHidden = true;
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
- }
- if (localLOGV) Slog.v(
- TAG, "Created surface " + this);
- }
- return mSurface;
- }
-
- void destroySurfaceLocked() {
- if (mAppToken != null && this == mAppToken.startingWindow) {
- mAppToken.startingDisplayed = false;
- }
-
- if (mSurface != null) {
- mDrawPending = false;
- mCommitDrawPending = false;
- mReadyToShow = false;
-
- int i = mChildWindows.size();
- while (i > 0) {
- i--;
- WindowState c = mChildWindows.get(i);
- c.mAttachedHidden = true;
- }
-
- if (mReportDestroySurface) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = true;
- try {
- mClient.dispatchGetNewSurface();
- // We'll really destroy on the next time around.
- return;
- } catch (RemoteException e) {
- }
- }
-
- try {
- if (DEBUG_VISIBILITY) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- Slog.w(TAG, "Window " + this + " destroying surface "
- + mSurface + ", session " + mSession, e);
- }
- if (SHOW_TRANSACTIONS) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
- }
- mSurface.destroy();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception thrown when destroying Window " + this
- + " surface " + mSurface + " session " + mSession
- + ": " + e.toString());
- }
-
- mSurfaceShown = false;
- mSurface = null;
- }
- }
-
- boolean finishDrawingLocked() {
- if (mDrawPending) {
- if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
- TAG, "finishDrawingLocked: " + mSurface);
- mCommitDrawPending = true;
- mDrawPending = false;
- return true;
- }
- return false;
- }
-
- // This must be called while inside a transaction.
- boolean commitFinishDrawingLocked(long currentTime) {
- //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
- if (!mCommitDrawPending) {
- return false;
- }
- mCommitDrawPending = false;
- mReadyToShow = true;
- final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
- final AppWindowToken atoken = mAppToken;
- if (atoken == null || atoken.allDrawn || starting) {
- performShowLocked();
- }
- return true;
- }
-
- // This must be called while inside a transaction.
- boolean performShowLocked() {
- if (DEBUG_VISIBILITY) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- Slog.v(TAG, "performShow on " + this
- + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
- + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
- }
- if (mReadyToShow && isReadyForDisplay()) {
- if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
- "SHOW (performShowLocked)", null);
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
- + " during animation: policyVis=" + mPolicyVisibility
- + " attHidden=" + mAttachedHidden
- + " tok.hiddenRequested="
- + (mAppToken != null ? mAppToken.hiddenRequested : false)
- + " tok.hidden="
- + (mAppToken != null ? mAppToken.hidden : false)
- + " animating=" + mAnimating
- + " tok animating="
- + (mAppToken != null ? mAppToken.animating : false));
- if (!showSurfaceRobustlyLocked(this)) {
- return false;
- }
- mLastAlpha = -1;
- mHasDrawn = true;
- mLastHidden = false;
- mReadyToShow = false;
- enableScreenIfNeededLocked();
-
- applyEnterAnimationLocked(this);
-
- int i = mChildWindows.size();
- while (i > 0) {
- i--;
- WindowState c = mChildWindows.get(i);
- if (c.mAttachedHidden) {
- c.mAttachedHidden = false;
- if (c.mSurface != null) {
- c.performShowLocked();
- // It hadn't been shown, which means layout not
- // performed on it, so now we want to make sure to
- // do a layout. If called from within the transaction
- // loop, this will cause it to restart with a new
- // layout.
- mLayoutNeeded = true;
- }
- }
- }
-
- if (mAttrs.type != TYPE_APPLICATION_STARTING
- && mAppToken != null) {
- mAppToken.firstWindowDrawn = true;
-
- if (mAppToken.startingData != null) {
- if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
- "Finish starting " + mToken
- + ": first real window is shown, no animation");
- // If this initial window is animating, stop it -- we
- // will do an animation to reveal it from behind the
- // starting window, so there is no need for it to also
- // be doing its own stuff.
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- // Make sure we clean up the animation.
- mAnimating = true;
- }
- mFinishedStarting.add(mAppToken);
- mH.sendEmptyMessage(H.FINISHED_STARTING);
- }
- mAppToken.updateReportedVisibilityLocked();
- }
- }
- return true;
- }
-
- // This must be called while inside a transaction. Returns true if
- // there is more animation to run.
- boolean stepAnimationLocked(long currentTime, int dw, int dh) {
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
- // We will run animations as long as the display isn't frozen.
-
- if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
- mHasTransformation = true;
- mHasLocalTransformation = true;
- if (!mLocalAnimating) {
- if (DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + this +
- " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
- " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
- mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
- mAnimation.setStartTime(currentTime);
- mLocalAnimating = true;
- mAnimating = true;
- }
- mTransformation.clear();
- final boolean more = mAnimation.getTransformation(
- currentTime, mTransformation);
- if (DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + mTransformation);
- if (more) {
- // we're not done!
- return true;
- }
- if (DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + this +
- " @ " + currentTime);
-
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- }
- //WindowManagerService.this.dump();
- }
- mHasLocalTransformation = false;
- if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
- && mAppToken.animation != null) {
- // When our app token is animating, we kind-of pretend like
- // we are as well. Note the mLocalAnimating mAnimationIsEntrance
- // part of this check means that we will only do this if
- // our window is not currently exiting, or it is not
- // locally animating itself. The idea being that one that
- // is exiting and doing a local animation should be removed
- // once that animation is done.
- mAnimating = true;
- mHasTransformation = true;
- mTransformation.clear();
- return false;
- } else if (mHasTransformation) {
- // Little trick to get through the path below to act like
- // we have finished an animation.
- mAnimating = true;
- } else if (isAnimating()) {
- mAnimating = true;
- }
- } else if (mAnimation != null) {
- // If the display is frozen, and there is a pending animation,
- // clear it and make sure we run the cleanup code.
- mAnimating = true;
- mLocalAnimating = true;
- mAnimation.cancel();
- mAnimation = null;
- }
-
- if (!mAnimating && !mLocalAnimating) {
- return false;
- }
-
- if (DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + this + ": exiting=" + mExiting
- + ", reportedVisible="
- + (mAppToken != null ? mAppToken.reportedVisible : false));
-
- mAnimating = false;
- mLocalAnimating = false;
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- }
- mAnimLayer = mLayer;
- if (mIsImWindow) {
- mAnimLayer += mInputMethodAnimLayerAdjustment;
- } else if (mIsWallpaper) {
- mAnimLayer += mWallpaperAnimLayerAdjustment;
- }
- if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
- + " anim layer: " + mAnimLayer);
- mHasTransformation = false;
- mHasLocalTransformation = false;
- if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
- + mPolicyVisibilityAfterAnim);
- }
- mPolicyVisibility = mPolicyVisibilityAfterAnim;
- if (!mPolicyVisibility) {
- if (mCurrentFocus == this) {
- mFocusMayChange = true;
- }
- // Window is no longer visible -- make sure if we were waiting
- // for it to be displayed before enabling the display, that
- // we allow the display to be enabled now.
- enableScreenIfNeededLocked();
- }
- }
- mTransformation.clear();
- if (mHasDrawn
- && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
- && mAppToken != null
- && mAppToken.firstWindowDrawn
- && mAppToken.startingData != null) {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
- + mToken + ": first real window done animating");
- mFinishedStarting.add(mAppToken);
- mH.sendEmptyMessage(H.FINISHED_STARTING);
- }
-
- finishExit();
-
- if (mAppToken != null) {
- mAppToken.updateReportedVisibilityLocked();
- }
-
- return false;
- }
-
- void finishExit() {
- if (DEBUG_ANIM) Slog.v(
- TAG, "finishExit in " + this
- + ": exiting=" + mExiting
- + " remove=" + mRemoveOnExit
- + " windowAnimating=" + isWindowAnimating());
-
- final int N = mChildWindows.size();
- for (int i=0; i<N; i++) {
- mChildWindows.get(i).finishExit();
- }
-
- if (!mExiting) {
- return;
- }
-
- if (isWindowAnimating()) {
- return;
- }
-
- if (localLOGV) Slog.v(
- TAG, "Exit animation finished in " + this
- + ": remove=" + mRemoveOnExit);
- if (mSurface != null) {
- mDestroySurface.add(this);
- mDestroying = true;
- if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
- mSurfaceShown = false;
- try {
- mSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error hiding surface in " + this, e);
- }
- mLastHidden = true;
- }
- mExiting = false;
- if (mRemoveOnExit) {
- mPendingRemove.add(this);
- mRemoveOnExit = false;
- }
- }
-
- boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- if (dsdx < .99999f || dsdx > 1.00001f) return false;
- if (dtdy < .99999f || dtdy > 1.00001f) return false;
- if (dtdx < -.000001f || dtdx > .000001f) return false;
- if (dsdy < -.000001f || dsdy > .000001f) return false;
- return true;
- }
-
- void computeShownFrameLocked() {
- final boolean selfTransformation = mHasLocalTransformation;
- Transformation attachedTransformation =
- (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
- ? mAttachedWindow.mTransformation : null;
- Transformation appTransformation =
- (mAppToken != null && mAppToken.hasTransformation)
- ? mAppToken.transformation : null;
-
- // Wallpapers are animated based on the "real" window they
- // are currently targeting.
- if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
- && mWallpaperTarget != null) {
- if (mWallpaperTarget.mHasLocalTransformation &&
- mWallpaperTarget.mAnimation != null &&
- !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
- attachedTransformation = mWallpaperTarget.mTransformation;
- if (DEBUG_WALLPAPER && attachedTransformation != null) {
- Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
- }
- }
- if (mWallpaperTarget.mAppToken != null &&
- mWallpaperTarget.mAppToken.hasTransformation &&
- mWallpaperTarget.mAppToken.animation != null &&
- !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
- appTransformation = mWallpaperTarget.mAppToken.transformation;
- if (DEBUG_WALLPAPER && appTransformation != null) {
- Slog.v(TAG, "WP target app xform: " + appTransformation);
- }
- }
- }
-
- final boolean screenAnimation = mScreenRotationAnimation != null
- && mScreenRotationAnimation.isAnimating();
- if (selfTransformation || attachedTransformation != null
- || appTransformation != null || screenAnimation) {
- // cache often used attributes locally
- final Rect frame = mFrame;
- final float tmpFloats[] = mTmpFloats;
- final Matrix tmpMatrix = mTmpMatrix;
-
- // Compute the desired transformation.
- tmpMatrix.setTranslate(0, 0);
- if (selfTransformation) {
- tmpMatrix.postConcat(mTransformation.getMatrix());
- }
- tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
- if (attachedTransformation != null) {
- tmpMatrix.postConcat(attachedTransformation.getMatrix());
- }
- if (appTransformation != null) {
- tmpMatrix.postConcat(appTransformation.getMatrix());
- }
- if (screenAnimation) {
- tmpMatrix.postConcat(
- mScreenRotationAnimation.getEnterTransformation().getMatrix());
- }
-
- // "convert" it into SurfaceFlinger's format
- // (a 2x2 matrix + an offset)
- // Here we must not transform the position of the surface
- // since it is already included in the transformation.
- //Slog.i(TAG, "Transform: " + matrix);
-
- mHaveMatrix = true;
- tmpMatrix.getValues(tmpFloats);
- mDsDx = tmpFloats[Matrix.MSCALE_X];
- mDtDx = tmpFloats[Matrix.MSKEW_Y];
- mDsDy = tmpFloats[Matrix.MSKEW_X];
- mDtDy = tmpFloats[Matrix.MSCALE_Y];
- int x = (int)tmpFloats[Matrix.MTRANS_X];
- int y = (int)tmpFloats[Matrix.MTRANS_Y];
- int w = frame.width();
- int h = frame.height();
- mShownFrame.set(x, y, x+w, y+h);
-
- // Now set the alpha... but because our current hardware
- // can't do alpha transformation on a non-opaque surface,
- // turn it off if we are running an animation that is also
- // transforming since it is more important to have that
- // animation be smooth.
- mShownAlpha = mAlpha;
- if (!mLimitedAlphaCompositing
- || (!PixelFormat.formatHasAlpha(mAttrs.format)
- || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
- && x == frame.left && y == frame.top))) {
- //Slog.i(TAG, "Applying alpha transform");
- if (selfTransformation) {
- mShownAlpha *= mTransformation.getAlpha();
- }
- if (attachedTransformation != null) {
- mShownAlpha *= attachedTransformation.getAlpha();
- }
- if (appTransformation != null) {
- mShownAlpha *= appTransformation.getAlpha();
- }
- if (screenAnimation) {
- mShownAlpha *=
- mScreenRotationAnimation.getEnterTransformation().getAlpha();
- }
- } else {
- //Slog.i(TAG, "Not applying alpha transform");
- }
-
- if (localLOGV) Slog.v(
- TAG, "Continuing animation in " + this +
- ": " + mShownFrame +
- ", alpha=" + mTransformation.getAlpha());
- return;
- }
-
- mShownFrame.set(mFrame);
- if (mXOffset != 0 || mYOffset != 0) {
- mShownFrame.offset(mXOffset, mYOffset);
- }
- mShownAlpha = mAlpha;
- mHaveMatrix = false;
- mDsDx = 1;
- mDtDx = 0;
- mDsDy = 0;
- mDtDy = 1;
- }
-
- /**
- * Is this window visible? It is not visible if there is no
- * surface, or we are in the process of running an exit animation
- * that will remove the surface, or its app token has been hidden.
- */
- public boolean isVisibleLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested)
- && !mExiting && !mDestroying;
- }
-
- /**
- * Like {@link #isVisibleLw}, but also counts a window that is currently
- * "hidden" behind the keyguard as visible. This allows us to apply
- * things like window flags that impact the keyguard.
- * XXX I am starting to think we need to have ANOTHER visibility flag
- * for this "hidden behind keyguard" state rather than overloading
- * mPolicyVisibility. Ungh.
- */
- public boolean isVisibleOrBehindKeyguardLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && !mAttachedHidden
- && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
- && !mDrawPending && !mCommitDrawPending
- && !mExiting && !mDestroying;
- }
-
- /**
- * Is this window visible, ignoring its app token? It is not visible
- * if there is no surface, or we are in the process of running an exit animation
- * that will remove the surface.
- */
- public boolean isWinVisibleLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested || atoken.animating)
- && !mExiting && !mDestroying;
- }
-
- /**
- * The same as isVisible(), but follows the current hidden state of
- * the associated app token, not the pending requested hidden state.
- */
- boolean isVisibleNow() {
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && !mRootToken.hidden && !mExiting && !mDestroying;
- }
-
- /**
- * Can this window possibly be a drag/drop target? The test here is
- * a combination of the above "visible now" with the check that the
- * Input Manager uses when discarding windows from input consideration.
- */
- boolean isPotentialDragTarget() {
- return isVisibleNow() && (mInputChannel != null) && !mRemoved;
- }
-
- /**
- * Same as isVisible(), but we also count it as visible between the
- * call to IWindowSession.add() and the first relayout().
- */
- boolean isVisibleOrAdding() {
- final AppWindowToken atoken = mAppToken;
- return ((mSurface != null && !mReportDestroySurface)
- || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
- && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested)
- && !mExiting && !mDestroying;
- }
-
- /**
- * Is this window currently on-screen? It is on-screen either if it
- * is visible or it is currently running an animation before no longer
- * being visible.
- */
- boolean isOnScreen() {
- final AppWindowToken atoken = mAppToken;
- if (atoken != null) {
- return mSurface != null && mPolicyVisibility && !mDestroying
- && ((!mAttachedHidden && !atoken.hiddenRequested)
- || mAnimation != null || atoken.animation != null);
- } else {
- return mSurface != null && mPolicyVisibility && !mDestroying
- && (!mAttachedHidden || mAnimation != null);
- }
- }
-
- /**
- * Like isOnScreen(), but we don't return true if the window is part
- * of a transition that has not yet been started.
- */
- boolean isReadyForDisplay() {
- if (mRootToken.waitingToShow &&
- mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
- return false;
- }
- final AppWindowToken atoken = mAppToken;
- final boolean animating = atoken != null
- ? (atoken.animation != null) : false;
- return mSurface != null && mPolicyVisibility && !mDestroying
- && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
- && !mRootToken.hidden)
- || mAnimation != null || animating);
- }
-
- /** Is the window or its container currently animating? */
- boolean isAnimating() {
- final WindowState attached = mAttachedWindow;
- final AppWindowToken atoken = mAppToken;
- return mAnimation != null
- || (attached != null && attached.mAnimation != null)
- || (atoken != null &&
- (atoken.animation != null
- || atoken.inPendingTransaction));
- }
-
- /** Is this window currently animating? */
- boolean isWindowAnimating() {
- return mAnimation != null;
- }
-
- /**
- * Like isOnScreen, but returns false if the surface hasn't yet
- * been drawn.
- */
- public boolean isDisplayedLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mDestroying
- && !mDrawPending && !mCommitDrawPending
- && ((!mAttachedHidden &&
- (atoken == null || !atoken.hiddenRequested))
- || mAnimating);
- }
-
- /**
- * Returns true if the window has a surface that it has drawn a
- * complete UI in to.
- */
- public boolean isDrawnLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && !mDestroying
- && !mDrawPending && !mCommitDrawPending;
- }
-
- /**
- * Return true if the window is opaque and fully drawn. This indicates
- * it may obscure windows behind it.
- */
- boolean isOpaqueDrawn() {
- return (mAttrs.format == PixelFormat.OPAQUE
- || mAttrs.type == TYPE_WALLPAPER)
- && mSurface != null && mAnimation == null
- && (mAppToken == null || mAppToken.animation == null)
- && !mDrawPending && !mCommitDrawPending;
- }
-
- /**
- * Return whether this window is wanting to have a translation
- * animation applied to it for an in-progress move. (Only makes
- * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
- */
- boolean shouldAnimateMove() {
- return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
- && (mFrame.top != mLastFrame.top
- || mFrame.left != mLastFrame.left)
- && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
- && mPolicy.isScreenOn();
- }
-
- boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
- return
- // only if the application is requesting compatible window
- (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
- // only if it's visible
- mHasDrawn && mViewVisibility == View.VISIBLE &&
- // and only if the application fills the compatible screen
- mFrame.left <= mCompatibleScreenFrame.left &&
- mFrame.top <= mCompatibleScreenFrame.top &&
- mFrame.right >= mCompatibleScreenFrame.right &&
- mFrame.bottom >= mCompatibleScreenFrame.bottom;
- }
-
- boolean isFullscreen(int screenWidth, int screenHeight) {
- return mFrame.left <= 0 && mFrame.top <= 0 &&
- mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
- }
-
- void removeLocked() {
- disposeInputChannel();
-
- if (mAttachedWindow != null) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
- mAttachedWindow.mChildWindows.remove(this);
- }
- destroySurfaceLocked();
- mSession.windowRemovedLocked();
- try {
- mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
- } catch (RuntimeException e) {
- // Ignore if it has already been removed (usually because
- // we are doing this as part of processing a death note.)
- }
- }
-
- void disposeInputChannel() {
- if (mInputChannel != null) {
- mInputManager.unregisterInputChannel(mInputChannel);
-
- mInputChannel.dispose();
- mInputChannel = null;
- }
- }
-
- private class DeathRecipient implements IBinder.DeathRecipient {
- public void binderDied() {
- try {
- synchronized(mWindowMap) {
- WindowState win = windowForClientLocked(mSession, mClient, false);
- Slog.i(TAG, "WIN DEATH: " + win);
- if (win != null) {
- removeWindowLocked(mSession, win);
- }
- }
- } catch (IllegalArgumentException ex) {
- // This will happen if the window has already been
- // removed.
- }
- }
- }
-
- /** Returns true if this window desires key events. */
- public final boolean canReceiveKeys() {
- return isVisibleOrAdding()
- && (mViewVisibility == View.VISIBLE)
- && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
- }
-
- public boolean hasDrawnLw() {
- return mHasDrawn;
- }
-
- public boolean showLw(boolean doAnimation) {
- return showLw(doAnimation, true);
- }
-
- boolean showLw(boolean doAnimation, boolean requestAnim) {
- if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
- return false;
- }
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
- if (doAnimation) {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
- + mPolicyVisibility + " mAnimation=" + mAnimation);
- if (mDisplayFrozen || !mPolicy.isScreenOn()) {
- doAnimation = false;
- } else if (mPolicyVisibility && mAnimation == null) {
- // Check for the case where we are currently visible and
- // not animating; we do not want to do animation at such a
- // point to become visible when we already are.
- doAnimation = false;
- }
- }
- mPolicyVisibility = true;
- mPolicyVisibilityAfterAnim = true;
- if (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
- }
- if (requestAnim) {
- requestAnimationLocked(0);
- }
- return true;
- }
-
- public boolean hideLw(boolean doAnimation) {
- return hideLw(doAnimation, true);
- }
-
- boolean hideLw(boolean doAnimation, boolean requestAnim) {
- if (doAnimation) {
- if (mDisplayFrozen || !mPolicy.isScreenOn()) {
- doAnimation = false;
- }
- }
- boolean current = doAnimation ? mPolicyVisibilityAfterAnim
- : mPolicyVisibility;
- if (!current) {
- return false;
- }
- if (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
- if (mAnimation == null) {
- doAnimation = false;
- }
- }
- if (doAnimation) {
- mPolicyVisibilityAfterAnim = false;
- } else {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
- mPolicyVisibilityAfterAnim = false;
- mPolicyVisibility = false;
- // Window is no longer visible -- make sure if we were waiting
- // for it to be displayed before enabling the display, that
- // we allow the display to be enabled now.
- enableScreenIfNeededLocked();
- if (mCurrentFocus == this) {
- mFocusMayChange = true;
- }
- }
- if (requestAnim) {
- requestAnimationLocked(0);
- }
- return true;
- }
-
- public void getTouchableRegion(Region outRegion) {
- final Rect frame = mFrame;
- switch (mTouchableInsets) {
- default:
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
- outRegion.set(frame);
- break;
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
- final Rect inset = mGivenContentInsets;
- outRegion.set(
- frame.left + inset.left, frame.top + inset.top,
- frame.right - inset.right, frame.bottom - inset.bottom);
- break;
- }
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
- final Rect inset = mGivenVisibleInsets;
- outRegion.set(
- frame.left + inset.left, frame.top + inset.top,
- frame.right - inset.right, frame.bottom - inset.bottom);
- break;
- }
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
- final Region givenTouchableRegion = mGivenTouchableRegion;
- outRegion.set(givenTouchableRegion);
- outRegion.translate(frame.left, frame.top);
- break;
- }
- }
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mSession="); pw.print(mSession);
- pw.print(" mClient="); pw.println(mClient.asBinder());
- pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
- if (mAttachedWindow != null || mLayoutAttached) {
- pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
- pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
- }
- if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
- pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
- pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
- pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
- pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
- }
- pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
- pw.print(" mSubLayer="); pw.print(mSubLayer);
- pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
- pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
- : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
- pw.print("="); pw.print(mAnimLayer);
- pw.print(" mLastLayer="); pw.println(mLastLayer);
- if (mSurface != null) {
- pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
- pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
- pw.print(" layer="); pw.print(mSurfaceLayer);
- pw.print(" alpha="); pw.print(mSurfaceAlpha);
- pw.print(" rect=("); pw.print(mSurfaceX);
- pw.print(","); pw.print(mSurfaceY);
- pw.print(") "); pw.print(mSurfaceW);
- pw.print(" x "); pw.println(mSurfaceH);
- }
- pw.print(prefix); pw.print("mToken="); pw.println(mToken);
- pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
- if (mAppToken != null) {
- pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
- }
- if (mTargetAppToken != null) {
- pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
- }
- pw.print(prefix); pw.print("mViewVisibility=0x");
- pw.print(Integer.toHexString(mViewVisibility));
- pw.print(" mLastHidden="); pw.print(mLastHidden);
- pw.print(" mHaveFrame="); pw.print(mHaveFrame);
- pw.print(" mObscured="); pw.println(mObscured);
- if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
- pw.print(prefix); pw.print("mPolicyVisibility=");
- pw.print(mPolicyVisibility);
- pw.print(" mPolicyVisibilityAfterAnim=");
- pw.print(mPolicyVisibilityAfterAnim);
- pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
- }
- if (!mRelayoutCalled) {
- pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
- }
- pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
- pw.print(" h="); pw.print(mRequestedHeight);
- pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
- if (mXOffset != 0 || mYOffset != 0) {
- pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
- pw.print(" y="); pw.println(mYOffset);
- }
- pw.print(prefix); pw.print("mGivenContentInsets=");
- mGivenContentInsets.printShortString(pw);
- pw.print(" mGivenVisibleInsets=");
- mGivenVisibleInsets.printShortString(pw);
- pw.println();
- if (mTouchableInsets != 0 || mGivenInsetsPending) {
- pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
- pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
- }
- pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
- pw.print(prefix); pw.print("mShownFrame=");
- mShownFrame.printShortString(pw);
- pw.print(" last="); mLastShownFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
- pw.print(" last="); mLastFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContainingFrame=");
- mContainingFrame.printShortString(pw);
- pw.print(" mParentFrame=");
- mParentFrame.printShortString(pw);
- pw.print(" mDisplayFrame=");
- mDisplayFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
- pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
- pw.print(" last="); mLastContentInsets.printShortString(pw);
- pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
- pw.print(" last="); mLastVisibleInsets.printShortString(pw);
- pw.println();
- if (mAnimating || mLocalAnimating || mAnimationIsEntrance
- || mAnimation != null) {
- pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
- pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
- pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
- pw.print(" mAnimation="); pw.println(mAnimation);
- }
- if (mHasTransformation || mHasLocalTransformation) {
- pw.print(prefix); pw.print("XForm: has=");
- pw.print(mHasTransformation);
- pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
- pw.print(" "); mTransformation.printShortString(pw);
- pw.println();
- }
- if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
- pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
- pw.print(" mAlpha="); pw.print(mAlpha);
- pw.print(" mLastAlpha="); pw.println(mLastAlpha);
- }
- if (mHaveMatrix) {
- pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
- pw.print(" mDtDx="); pw.print(mDtDx);
- pw.print(" mDsDy="); pw.print(mDsDy);
- pw.print(" mDtDy="); pw.println(mDtDy);
- }
- pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
- pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
- pw.print(" mReadyToShow="); pw.print(mReadyToShow);
- pw.print(" mHasDrawn="); pw.println(mHasDrawn);
- if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
- pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
- pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
- pw.print(" mDestroying="); pw.print(mDestroying);
- pw.print(" mRemoved="); pw.println(mRemoved);
- }
- if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
- pw.print(prefix); pw.print("mOrientationChanging=");
- pw.print(mOrientationChanging);
- pw.print(" mAppFreezing="); pw.print(mAppFreezing);
- pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
- }
- if (mHScale != 1 || mVScale != 1) {
- pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
- pw.print(" mVScale="); pw.println(mVScale);
- }
- if (mWallpaperX != -1 || mWallpaperY != -1) {
- pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
- pw.print(" mWallpaperY="); pw.println(mWallpaperY);
- }
- if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
- pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
- pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
- }
- }
-
- String makeInputChannelName() {
- return Integer.toHexString(System.identityHashCode(this))
- + " " + mAttrs.getTitle();
- }
-
- @Override
- public String toString() {
- if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
- || mWasPaused != mToken.paused) {
- mLastTitle = mAttrs.getTitle();
- mWasPaused = mToken.paused;
- mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
- + " " + mLastTitle + " paused=" + mWasPaused + "}";
- }
- return mStringNameCache;
- }
- }
-
- // -------------------------------------------------------------
- // Window Token State
- // -------------------------------------------------------------
-
- class WindowToken {
- // The actual token.
- final IBinder token;
-
- // The type of window this token is for, as per WindowManager.LayoutParams.
- final int windowType;
-
- // Set if this token was explicitly added by a client, so should
- // not be removed when all windows are removed.
- final boolean explicit;
-
- // For printing.
- String stringName;
-
- // If this is an AppWindowToken, this is non-null.
- AppWindowToken appWindowToken;
-
- // All of the windows associated with this token.
- final ArrayList<WindowState> windows = new ArrayList<WindowState>();
-
- // Is key dispatching paused for this token?
- boolean paused = false;
-
- // Should this token's windows be hidden?
- boolean hidden;
-
- // Temporary for finding which tokens no longer have visible windows.
- boolean hasVisible;
-
- // Set to true when this token is in a pending transaction where it
- // will be shown.
- boolean waitingToShow;
-
- // Set to true when this token is in a pending transaction where it
- // will be hidden.
- boolean waitingToHide;
-
- // Set to true when this token is in a pending transaction where its
- // windows will be put to the bottom of the list.
- boolean sendingToBottom;
-
- // Set to true when this token is in a pending transaction where its
- // windows will be put to the top of the list.
- boolean sendingToTop;
-
- WindowToken(IBinder _token, int type, boolean _explicit) {
- token = _token;
- windowType = type;
- explicit = _explicit;
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("token="); pw.println(token);
- pw.print(prefix); pw.print("windows="); pw.println(windows);
- pw.print(prefix); pw.print("windowType="); pw.print(windowType);
- pw.print(" hidden="); pw.print(hidden);
- pw.print(" hasVisible="); pw.println(hasVisible);
- if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
- pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
- pw.print(" waitingToHide="); pw.print(waitingToHide);
- pw.print(" sendingToBottom="); pw.print(sendingToBottom);
- pw.print(" sendingToTop="); pw.println(sendingToTop);
- }
- }
-
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("WindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName;
- }
- };
-
- class AppWindowToken extends WindowToken {
- // Non-null only for application tokens.
- final IApplicationToken appToken;
-
- // All of the windows and child windows that are included in this
- // application token. Note this list is NOT sorted!
- final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
-
- int groupId = -1;
- boolean appFullscreen;
- int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
- // The input dispatching timeout for this application token in nanoseconds.
- long inputDispatchingTimeoutNanos;
-
- // These are used for determining when all windows associated with
- // an activity have been drawn, so they can be made visible together
- // at the same time.
- int lastTransactionSequence = mTransactionSequence-1;
- int numInterestingWindows;
- int numDrawnWindows;
- boolean inPendingTransaction;
- boolean allDrawn;
-
- // Is this token going to be hidden in a little while? If so, it
- // won't be taken into account for setting the screen orientation.
- boolean willBeHidden;
-
- // Is this window's surface needed? This is almost like hidden, except
- // it will sometimes be true a little earlier: when the token has
- // been shown, but is still waiting for its app transition to execute
- // before making its windows shown.
- boolean hiddenRequested;
-
- // Have we told the window clients to hide themselves?
- boolean clientHidden;
-
- // Last visibility state we reported to the app token.
- boolean reportedVisible;
-
- // Set to true when the token has been removed from the window mgr.
- boolean removed;
-
- // Have we been asked to have this token keep the screen frozen?
- boolean freezingScreen;
-
- boolean animating;
- Animation animation;
- boolean hasTransformation;
- final Transformation transformation = new Transformation();
-
- // Offset to the window of all layers in the token, for use by
- // AppWindowToken animations.
- int animLayerAdjustment;
-
- // Information about an application starting window if displayed.
- StartingData startingData;
- WindowState startingWindow;
- View startingView;
- boolean startingDisplayed;
- boolean startingMoved;
- boolean firstWindowDrawn;
-
- // Input application handle used by the input dispatcher.
- InputApplicationHandle mInputApplicationHandle;
-
- AppWindowToken(IApplicationToken _token) {
- super(_token.asBinder(),
- WindowManager.LayoutParams.TYPE_APPLICATION, true);
- appWindowToken = this;
- appToken = _token;
- mInputApplicationHandle = new InputApplicationHandle(this);
- }
-
- public void setAnimation(Animation anim) {
- if (localLOGV) Slog.v(
- TAG, "Setting animation in " + this + ": " + anim);
- animation = anim;
- animating = false;
- anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(mTransitionAnimationScale);
- int zorder = anim.getZAdjustment();
- int adj = 0;
- if (zorder == Animation.ZORDER_TOP) {
- adj = TYPE_LAYER_OFFSET;
- } else if (zorder == Animation.ZORDER_BOTTOM) {
- adj = -TYPE_LAYER_OFFSET;
- }
-
- if (animLayerAdjustment != adj) {
- animLayerAdjustment = adj;
- updateLayers();
- }
- }
-
- public void setDummyAnimation() {
- if (animation == null) {
- if (localLOGV) Slog.v(
- TAG, "Setting dummy animation in " + this);
- animation = sDummyAnimation;
- }
- }
-
- public void clearAnimation() {
- if (animation != null) {
- animation = null;
- animating = true;
- }
- }
-
- void updateLayers() {
- final int N = allAppWindows.size();
- final int adj = animLayerAdjustment;
- for (int i=0; i<N; i++) {
- WindowState w = allAppWindows.get(i);
- w.mAnimLayer = w.mLayer + adj;
- if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
- + w.mAnimLayer);
- if (w == mInputMethodTarget && !mInputMethodTargetWaitingAnim) {
- setInputMethodAnimLayerAdjustment(adj);
- }
- if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
- setWallpaperAnimLayerAdjustmentLocked(adj);
- }
- }
- }
-
- void sendAppVisibilityToClients() {
- final int N = allAppWindows.size();
- for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
- if (win == startingWindow && clientHidden) {
- // Don't hide the starting window.
- continue;
- }
- try {
- if (DEBUG_VISIBILITY) Slog.v(TAG,
- "Setting visibility of " + win + ": " + (!clientHidden));
- win.mClient.dispatchAppVisibility(!clientHidden);
- } catch (RemoteException e) {
- }
- }
- }
-
- void showAllWindowsLocked() {
- final int NW = allAppWindows.size();
- for (int i=0; i<NW; i++) {
- WindowState w = allAppWindows.get(i);
- if (DEBUG_VISIBILITY) Slog.v(TAG,
- "performing show on: " + w);
- w.performShowLocked();
- }
- }
-
- // This must be called while inside a transaction.
- boolean stepAnimationLocked(long currentTime, int dw, int dh) {
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
- // We will run animations as long as the display isn't frozen.
-
- if (animation == sDummyAnimation) {
- // This guy is going to animate, but not yet. For now count
- // it as not animating for purposes of scheduling transactions;
- // when it is really time to animate, this will be set to
- // a real animation and the next call will execute normally.
- return false;
- }
-
- if ((allDrawn || animating || startingDisplayed) && animation != null) {
- if (!animating) {
- if (DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + this +
- " @ " + currentTime + ": dw=" + dw + " dh=" + dh
- + " scale=" + mTransitionAnimationScale
- + " allDrawn=" + allDrawn + " animating=" + animating);
- animation.initialize(dw, dh, dw, dh);
- animation.setStartTime(currentTime);
- animating = true;
- }
- transformation.clear();
- final boolean more = animation.getTransformation(
- currentTime, transformation);
- if (DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + transformation);
- if (more) {
- // we're done!
- hasTransformation = true;
- return true;
- }
- if (DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + this +
- " @ " + currentTime);
- animation = null;
- }
- } else if (animation != null) {
- // If the display is frozen, and there is a pending animation,
- // clear it and make sure we run the cleanup code.
- animating = true;
- animation = null;
- }
-
- hasTransformation = false;
-
- if (!animating) {
- return false;
- }
-
- clearAnimation();
- animating = false;
- if (animLayerAdjustment != 0) {
- animLayerAdjustment = 0;
- updateLayers();
- }
- if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
- moveInputMethodWindowsIfNeededLocked(true);
- }
-
- if (DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + this
- + ": reportedVisible=" + reportedVisible);
-
- transformation.clear();
-
- final int N = windows.size();
- for (int i=0; i<N; i++) {
- windows.get(i).finishExit();
- }
- updateReportedVisibilityLocked();
-
- return false;
- }
-
- void updateReportedVisibilityLocked() {
- if (appToken == null) {
- return;
- }
-
- int numInteresting = 0;
- int numVisible = 0;
- boolean nowGone = true;
-
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
- final int N = allAppWindows.size();
- for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
- if (win == startingWindow || win.mAppFreezing
- || win.mViewVisibility != View.VISIBLE
- || win.mAttrs.type == TYPE_APPLICATION_STARTING
- || win.mDestroying) {
- continue;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG, "Win " + win + ": isDrawn="
- + win.isDrawnLw()
- + ", isAnimating=" + win.isAnimating());
- if (!win.isDrawnLw()) {
- Slog.v(TAG, "Not displayed: s=" + win.mSurface
- + " pv=" + win.mPolicyVisibility
- + " dp=" + win.mDrawPending
- + " cdp=" + win.mCommitDrawPending
- + " ah=" + win.mAttachedHidden
- + " th="
- + (win.mAppToken != null
- ? win.mAppToken.hiddenRequested : false)
- + " a=" + win.mAnimating);
- }
- }
- numInteresting++;
- if (win.isDrawnLw()) {
- if (!win.isAnimating()) {
- numVisible++;
- }
- nowGone = false;
- } else if (win.isAnimating()) {
- nowGone = false;
- }
- }
-
- boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
- if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
- + numInteresting + " visible=" + numVisible);
- if (nowVisible != reportedVisible) {
- if (DEBUG_VISIBILITY) Slog.v(
- TAG, "Visibility changed in " + this
- + ": vis=" + nowVisible);
- reportedVisible = nowVisible;
- Message m = mH.obtainMessage(
- H.REPORT_APPLICATION_TOKEN_WINDOWS,
- nowVisible ? 1 : 0,
- nowGone ? 1 : 0,
- this);
- mH.sendMessage(m);
- }
- }
-
- WindowState findMainWindow() {
- int j = windows.size();
- while (j > 0) {
- j--;
- WindowState win = windows.get(j);
- if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
- || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
- return win;
- }
- }
- return null;
- }
-
- void dump(PrintWriter pw, String prefix) {
- super.dump(pw, prefix);
- if (appToken != null) {
- pw.print(prefix); pw.println("app=true");
- }
- if (allAppWindows.size() > 0) {
- pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
- }
- pw.print(prefix); pw.print("groupId="); pw.print(groupId);
- pw.print(" appFullscreen="); pw.print(appFullscreen);
- pw.print(" requestedOrientation="); pw.println(requestedOrientation);
- pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
- pw.print(" clientHidden="); pw.print(clientHidden);
- pw.print(" willBeHidden="); pw.print(willBeHidden);
- pw.print(" reportedVisible="); pw.println(reportedVisible);
- if (paused || freezingScreen) {
- pw.print(prefix); pw.print("paused="); pw.print(paused);
- pw.print(" freezingScreen="); pw.println(freezingScreen);
- }
- if (numInterestingWindows != 0 || numDrawnWindows != 0
- || inPendingTransaction || allDrawn) {
- pw.print(prefix); pw.print("numInterestingWindows=");
- pw.print(numInterestingWindows);
- pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
- pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
- pw.print(" allDrawn="); pw.println(allDrawn);
- }
- if (animating || animation != null) {
- pw.print(prefix); pw.print("animating="); pw.print(animating);
- pw.print(" animation="); pw.println(animation);
- }
- if (hasTransformation) {
- pw.print(prefix); pw.print("XForm: ");
- transformation.printShortString(pw);
- pw.println();
- }
- if (animLayerAdjustment != 0) {
- pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
- }
- if (startingData != null || removed || firstWindowDrawn) {
- pw.print(prefix); pw.print("startingData="); pw.print(startingData);
- pw.print(" removed="); pw.print(removed);
- pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
- }
- if (startingWindow != null || startingView != null
- || startingDisplayed || startingMoved) {
- pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
- pw.print(" startingView="); pw.print(startingView);
- pw.print(" startingDisplayed="); pw.print(startingDisplayed);
- pw.print(" startingMoved"); pw.println(startingMoved);
- }
- }
-
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("AppWindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName;
- }
- }
-
- // -------------------------------------------------------------
- // DummyAnimation
- // -------------------------------------------------------------
-
// This is an animation that does nothing: it just immediately finishes
// itself every time it is called. It is used as a stub animation in cases
// where we want to synchronize multiple things that may be animating.
@@ -8913,26 +5826,7 @@
// Async Handler
// -------------------------------------------------------------
- static final class StartingData {
- final String pkg;
- final int theme;
- final CharSequence nonLocalizedLabel;
- final int labelRes;
- final int icon;
- final int windowFlags;
-
- StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
- int _labelRes, int _icon, int _windowFlags) {
- pkg = _pkg;
- theme = _theme;
- nonLocalizedLabel = _nonLocalizedLabel;
- labelRes = _labelRes;
- icon = _icon;
- windowFlags = _windowFlags;
- }
- }
-
- private final class H extends Handler {
+ final class H extends Handler {
public static final int REPORT_FOCUS_CHANGE = 2;
public static final int REPORT_LOSING_FOCUS = 3;
public static final int ANIMATE = 4;
@@ -9342,7 +6236,7 @@
IInputContext inputContext) {
if (client == null) throw new IllegalArgumentException("null client");
if (inputContext == null) throw new IllegalArgumentException("null inputContext");
- Session session = new Session(client, inputContext);
+ Session session = new Session(this, client, inputContext);
return session;
}
@@ -11476,148 +8370,6 @@
return val;
}
- static class Watermark {
- final String[] mTokens;
- final String mText;
- final Paint mTextPaint;
- final int mTextWidth;
- final int mTextHeight;
- final int mTextAscent;
- final int mTextDescent;
- final int mDeltaX;
- final int mDeltaY;
-
- Surface mSurface;
- int mLastDW;
- int mLastDH;
- boolean mDrawNeeded;
-
- Watermark(Display display, SurfaceSession session, String[] tokens) {
- final DisplayMetrics dm = new DisplayMetrics();
- display.getMetrics(dm);
-
- if (false) {
- Log.i(TAG, "*********************** WATERMARK");
- for (int i=0; i<tokens.length; i++) {
- Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
- }
- }
-
- mTokens = tokens;
-
- StringBuilder builder = new StringBuilder(32);
- int len = mTokens[0].length();
- len = len & ~1;
- for (int i=0; i<len; i+=2) {
- int c1 = mTokens[0].charAt(i);
- int c2 = mTokens[0].charAt(i+1);
- if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
- else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
- else c1 -= '0';
- if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
- else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
- else c2 -= '0';
- builder.append((char)(255-((c1*16)+c2)));
- }
- mText = builder.toString();
- if (false) {
- Log.i(TAG, "Final text: " + mText);
- }
-
- int fontSize = getPropertyInt(tokens, 1,
- TypedValue.COMPLEX_UNIT_DIP, 20, dm);
-
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mTextPaint.setTextSize(fontSize);
- mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
-
- FontMetricsInt fm = mTextPaint.getFontMetricsInt();
- mTextWidth = (int)mTextPaint.measureText(mText);
- mTextAscent = fm.ascent;
- mTextDescent = fm.descent;
- mTextHeight = fm.descent - fm.ascent;
-
- mDeltaX = getPropertyInt(tokens, 2,
- TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
- mDeltaY = getPropertyInt(tokens, 3,
- TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
- int shadowColor = getPropertyInt(tokens, 4,
- TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
- int color = getPropertyInt(tokens, 5,
- TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
- int shadowRadius = getPropertyInt(tokens, 6,
- TypedValue.COMPLEX_UNIT_PX, 7, dm);
- int shadowDx = getPropertyInt(tokens, 8,
- TypedValue.COMPLEX_UNIT_PX, 0, dm);
- int shadowDy = getPropertyInt(tokens, 9,
- TypedValue.COMPLEX_UNIT_PX, 0, dm);
-
- mTextPaint.setColor(color);
- mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
-
- try {
- mSurface = new Surface(session, 0,
- "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
- mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
- mSurface.setPosition(0, 0);
- mSurface.show();
- } catch (OutOfResourcesException e) {
- }
- }
-
- void positionSurface(int dw, int dh) {
- if (mLastDW != dw || mLastDH != dh) {
- mLastDW = dw;
- mLastDH = dh;
- mSurface.setSize(dw, dh);
- mDrawNeeded = true;
- }
- }
-
- void drawIfNeeded() {
- if (mDrawNeeded) {
- final int dw = mLastDW;
- final int dh = mLastDH;
-
- mDrawNeeded = false;
- Rect dirty = new Rect(0, 0, dw, dh);
- Canvas c = null;
- try {
- c = mSurface.lockCanvas(dirty);
- } catch (IllegalArgumentException e) {
- } catch (OutOfResourcesException e) {
- }
- if (c != null) {
- c.drawColor(0, PorterDuff.Mode.CLEAR);
-
- int deltaX = mDeltaX;
- int deltaY = mDeltaY;
-
- // deltaX shouldn't be close to a round fraction of our
- // x step, or else things will line up too much.
- int div = (dw+mTextWidth)/deltaX;
- int rem = (dw+mTextWidth) - (div*deltaX);
- int qdelta = deltaX/4;
- if (rem < qdelta || rem > (deltaX-qdelta)) {
- deltaX += deltaX/3;
- }
-
- int y = -mTextHeight;
- int x = -mTextWidth;
- while (y < (dh+mTextHeight)) {
- c.drawText(mText, x, y, mTextPaint);
- x += deltaX;
- if (x >= dw) {
- x -= (dw+mTextWidth);
- y += deltaY;
- }
- }
- mSurface.unlockCanvasAndPost(c);
- }
- }
- }
- }
-
void createWatermark() {
if (mWatermark != null) {
return;
@@ -11899,190 +8651,6 @@
synchronized (mKeyguardTokenWatcher) { }
}
- /**
- * DimAnimator class that controls the dim animation. This holds the surface and
- * all state used for dim animation.
- */
- private static class DimAnimator {
- Surface mDimSurface;
- boolean mDimShown = false;
- float mDimCurrentAlpha;
- float mDimTargetAlpha;
- float mDimDeltaPerMs;
- long mLastDimAnimTime;
-
- int mLastDimWidth, mLastDimHeight;
-
- DimAnimator (SurfaceSession session) {
- if (mDimSurface == null) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": CREATE");
- try {
- mDimSurface = new Surface(session, 0,
- "DimSurface",
- -1, 16, 16, PixelFormat.OPAQUE,
- Surface.FX_SURFACE_DIM);
- mDimSurface.setAlpha(0.0f);
- } catch (Exception e) {
- Slog.e(TAG, "Exception creating Dim surface", e);
- }
- }
- }
-
- /**
- * Show the dim surface.
- */
- void show(int dw, int dh) {
- if (!mDimShown) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
- dw + "x" + dh + ")");
- mDimShown = true;
- try {
- mLastDimWidth = dw;
- mLastDimHeight = dh;
- mDimSurface.setPosition(0, 0);
- mDimSurface.setSize(dw, dh);
- mDimSurface.show();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Failure showing dim surface", e);
- }
- } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
- mLastDimWidth = dw;
- mLastDimHeight = dh;
- mDimSurface.setSize(dw, dh);
- }
- }
-
- /**
- * Set's the dim surface's layer and update dim parameters that will be used in
- * {@link updateSurface} after all windows are examined.
- */
- void updateParameters(Resources res, WindowState w, long currentTime) {
- mDimSurface.setLayer(w.mAnimLayer-1);
-
- final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
- + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
- if (mDimTargetAlpha != target) {
- // If the desired dim level has changed, then
- // start an animation to it.
- mLastDimAnimTime = currentTime;
- long duration = (w.mAnimating && w.mAnimation != null)
- ? w.mAnimation.computeDurationHint()
- : DEFAULT_DIM_DURATION;
- if (target > mDimTargetAlpha) {
- TypedValue tv = new TypedValue();
- res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
- tv, true);
- if (tv.type == TypedValue.TYPE_FRACTION) {
- duration = (long)tv.getFraction((float)duration, (float)duration);
- } else if (tv.type >= TypedValue.TYPE_FIRST_INT
- && tv.type <= TypedValue.TYPE_LAST_INT) {
- duration = tv.data;
- }
- }
- if (duration < 1) {
- // Don't divide by zero
- duration = 1;
- }
- mDimTargetAlpha = target;
- mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
- }
- }
-
- /**
- * Updating the surface's alpha. Returns true if the animation continues, or returns
- * false when the animation is finished and the dim surface is hidden.
- */
- boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
- if (!dimming) {
- if (mDimTargetAlpha != 0) {
- mLastDimAnimTime = currentTime;
- mDimTargetAlpha = 0;
- mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
- }
- }
-
- boolean animating = false;
- if (mLastDimAnimTime != 0) {
- mDimCurrentAlpha += mDimDeltaPerMs
- * (currentTime-mLastDimAnimTime);
- boolean more = true;
- if (displayFrozen) {
- // If the display is frozen, there is no reason to animate.
- more = false;
- } else if (mDimDeltaPerMs > 0) {
- if (mDimCurrentAlpha > mDimTargetAlpha) {
- more = false;
- }
- } else if (mDimDeltaPerMs < 0) {
- if (mDimCurrentAlpha < mDimTargetAlpha) {
- more = false;
- }
- } else {
- more = false;
- }
-
- // Do we need to continue animating?
- if (more) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": alpha=" + mDimCurrentAlpha);
- mLastDimAnimTime = currentTime;
- mDimSurface.setAlpha(mDimCurrentAlpha);
- animating = true;
- } else {
- mDimCurrentAlpha = mDimTargetAlpha;
- mLastDimAnimTime = 0;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
- mDimSurface.setAlpha(mDimCurrentAlpha);
- if (!dimming) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
- + ": HIDE");
- try {
- mDimSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Illegal argument exception hiding dim surface");
- }
- mDimShown = false;
- }
- }
- }
- return animating;
- }
-
- public void printTo(PrintWriter pw) {
- pw.print(" mDimShown="); pw.print(mDimShown);
- pw.print(" current="); pw.print(mDimCurrentAlpha);
- pw.print(" target="); pw.print(mDimTargetAlpha);
- pw.print(" delta="); pw.print(mDimDeltaPerMs);
- pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
- }
- }
-
- /**
- * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
- * This is used for opening/closing transition for apps in compatible mode.
- */
- private static class FadeInOutAnimation extends Animation {
- boolean mFadeIn;
-
- public FadeInOutAnimation(boolean fadeIn) {
- setInterpolator(new AccelerateInterpolator());
- setDuration(DEFAULT_FADE_IN_OUT_DURATION);
- mFadeIn = fadeIn;
- }
-
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- float x = interpolatedTime;
- if (!mFadeIn) {
- x = 1.0f - x; // reverse the interpolation for fade out
- }
- t.setAlpha(x);
- }
- }
-
public interface OnHardKeyboardStatusChangeListener {
public void onHardKeyboardStatusChange(boolean available, boolean enabled);
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
new file mode 100644
index 0000000..d0eec89
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -0,0 +1,1623 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.res.Configuration;
+import android.graphics.Matrix;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.IApplicationToken;
+import android.view.IWindow;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+import android.view.WindowManager.LayoutParams;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * A window in the window manager.
+ */
+final class WindowState implements WindowManagerPolicy.WindowState {
+ final WindowManagerService mService;
+ final Session mSession;
+ final IWindow mClient;
+ WindowToken mToken;
+ WindowToken mRootToken;
+ AppWindowToken mAppToken;
+ AppWindowToken mTargetAppToken;
+ final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
+ final DeathRecipient mDeathRecipient;
+ final WindowState mAttachedWindow;
+ final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
+ final int mBaseLayer;
+ final int mSubLayer;
+ final boolean mLayoutAttached;
+ final boolean mIsImWindow;
+ final boolean mIsWallpaper;
+ final boolean mIsFloatingLayer;
+ int mViewVisibility;
+ boolean mPolicyVisibility = true;
+ boolean mPolicyVisibilityAfterAnim = true;
+ boolean mAppFreezing;
+ Surface mSurface;
+ boolean mReportDestroySurface;
+ boolean mSurfacePendingDestroy;
+ boolean mAttachedHidden; // is our parent window hidden?
+ boolean mLastHidden; // was this window last hidden?
+ boolean mWallpaperVisible; // for wallpaper, what was last vis report?
+ int mRequestedWidth;
+ int mRequestedHeight;
+ int mLastRequestedWidth;
+ int mLastRequestedHeight;
+ int mLayer;
+ int mAnimLayer;
+ int mLastLayer;
+ boolean mHaveFrame;
+ boolean mObscured;
+ boolean mTurnOnScreen;
+
+ int mLayoutSeq = -1;
+
+ Configuration mConfiguration = null;
+
+ // Actual frame shown on-screen (may be modified by animation)
+ final Rect mShownFrame = new Rect();
+ final Rect mLastShownFrame = new Rect();
+
+ /**
+ * Set when we have changed the size of the surface, to know that
+ * we must tell them application to resize (and thus redraw itself).
+ */
+ boolean mSurfaceResized;
+
+ /**
+ * Insets that determine the actually visible area
+ */
+ final Rect mVisibleInsets = new Rect();
+ final Rect mLastVisibleInsets = new Rect();
+ boolean mVisibleInsetsChanged;
+
+ /**
+ * Insets that are covered by system windows
+ */
+ final Rect mContentInsets = new Rect();
+ final Rect mLastContentInsets = new Rect();
+ boolean mContentInsetsChanged;
+
+ /**
+ * Set to true if we are waiting for this window to receive its
+ * given internal insets before laying out other windows based on it.
+ */
+ boolean mGivenInsetsPending;
+
+ /**
+ * These are the content insets that were given during layout for
+ * this window, to be applied to windows behind it.
+ */
+ final Rect mGivenContentInsets = new Rect();
+
+ /**
+ * These are the visible insets that were given during layout for
+ * this window, to be applied to windows behind it.
+ */
+ final Rect mGivenVisibleInsets = new Rect();
+
+ /**
+ * This is the given touchable area relative to the window frame, or null if none.
+ */
+ final Region mGivenTouchableRegion = new Region();
+
+ /**
+ * Flag indicating whether the touchable region should be adjusted by
+ * the visible insets; if false the area outside the visible insets is
+ * NOT touchable, so we must use those to adjust the frame during hit
+ * tests.
+ */
+ int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
+
+ // Current transformation being applied.
+ boolean mHaveMatrix;
+ float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
+ float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
+ float mHScale=1, mVScale=1;
+ float mLastHScale=1, mLastVScale=1;
+ final Matrix mTmpMatrix = new Matrix();
+
+ // "Real" frame that the application sees.
+ final Rect mFrame = new Rect();
+ final Rect mLastFrame = new Rect();
+
+ final Rect mContainingFrame = new Rect();
+ final Rect mDisplayFrame = new Rect();
+ final Rect mContentFrame = new Rect();
+ final Rect mParentFrame = new Rect();
+ final Rect mVisibleFrame = new Rect();
+
+ boolean mContentChanged;
+
+ float mShownAlpha = 1;
+ float mAlpha = 1;
+ float mLastAlpha = 1;
+
+ // Set to true if, when the window gets displayed, it should perform
+ // an enter animation.
+ boolean mEnterAnimationPending;
+
+ // Currently running animation.
+ boolean mAnimating;
+ boolean mLocalAnimating;
+ Animation mAnimation;
+ boolean mAnimationIsEntrance;
+ boolean mHasTransformation;
+ boolean mHasLocalTransformation;
+ final Transformation mTransformation = new Transformation();
+
+ // If a window showing a wallpaper: the requested offset for the
+ // wallpaper; if a wallpaper window: the currently applied offset.
+ float mWallpaperX = -1;
+ float mWallpaperY = -1;
+
+ // If a window showing a wallpaper: what fraction of the offset
+ // range corresponds to a full virtual screen.
+ float mWallpaperXStep = -1;
+ float mWallpaperYStep = -1;
+
+ // Wallpaper windows: pixels offset based on above variables.
+ int mXOffset;
+ int mYOffset;
+
+ // This is set after IWindowSession.relayout() has been called at
+ // least once for the window. It allows us to detect the situation
+ // where we don't yet have a surface, but should have one soon, so
+ // we can give the window focus before waiting for the relayout.
+ boolean mRelayoutCalled;
+
+ // This is set after the Surface has been created but before the
+ // window has been drawn. During this time the surface is hidden.
+ boolean mDrawPending;
+
+ // This is set after the window has finished drawing for the first
+ // time but before its surface is shown. The surface will be
+ // displayed when the next layout is run.
+ boolean mCommitDrawPending;
+
+ // This is set during the time after the window's drawing has been
+ // committed, and before its surface is actually shown. It is used
+ // to delay showing the surface until all windows in a token are ready
+ // to be shown.
+ boolean mReadyToShow;
+
+ // Set when the window has been shown in the screen the first time.
+ boolean mHasDrawn;
+
+ // Currently running an exit animation?
+ boolean mExiting;
+
+ // Currently on the mDestroySurface list?
+ boolean mDestroying;
+
+ // Completely remove from window manager after exit animation?
+ boolean mRemoveOnExit;
+
+ // Set when the orientation is changing and this window has not yet
+ // been updated for the new orientation.
+ boolean mOrientationChanging;
+
+ // Is this window now (or just being) removed?
+ boolean mRemoved;
+
+ // Temp for keeping track of windows that have been removed when
+ // rebuilding window list.
+ boolean mRebuilding;
+
+ // For debugging, this is the last information given to the surface flinger.
+ boolean mSurfaceShown;
+ int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
+ int mSurfaceLayer;
+ float mSurfaceAlpha;
+
+ // Input channel and input window handle used by the input dispatcher.
+ InputWindowHandle mInputWindowHandle;
+ InputChannel mInputChannel;
+
+ // Used to improve performance of toString()
+ String mStringNameCache;
+ CharSequence mLastTitle;
+ boolean mWasPaused;
+
+ WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
+ WindowState attachedWindow, WindowManager.LayoutParams a,
+ int viewVisibility) {
+ mService = service;
+ mSession = s;
+ mClient = c;
+ mToken = token;
+ mAttrs.copyFrom(a);
+ mViewVisibility = viewVisibility;
+ DeathRecipient deathRecipient = new DeathRecipient();
+ mAlpha = a.alpha;
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
+ + " token=" + token + " (" + mAttrs.token + ")");
+ try {
+ c.asBinder().linkToDeath(deathRecipient, 0);
+ } catch (RemoteException e) {
+ mDeathRecipient = null;
+ mAttachedWindow = null;
+ mLayoutAttached = false;
+ mIsImWindow = false;
+ mIsWallpaper = false;
+ mIsFloatingLayer = false;
+ mBaseLayer = 0;
+ mSubLayer = 0;
+ return;
+ }
+ mDeathRecipient = deathRecipient;
+
+ if ((mAttrs.type >= FIRST_SUB_WINDOW &&
+ mAttrs.type <= LAST_SUB_WINDOW)) {
+ // The multiplier here is to reserve space for multiple
+ // windows in the same type layer.
+ mBaseLayer = mService.mPolicy.windowTypeToLayerLw(
+ attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ mSubLayer = mService.mPolicy.subWindowTypeToLayerLw(a.type);
+ mAttachedWindow = attachedWindow;
+ if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Adding " + this + " to " + mAttachedWindow);
+ mAttachedWindow.mChildWindows.add(this);
+ mLayoutAttached = mAttrs.type !=
+ WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+ mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
+ || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
+ mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
+ mIsFloatingLayer = mIsImWindow || mIsWallpaper;
+ } else {
+ // The multiplier here is to reserve space for multiple
+ // windows in the same type layer.
+ mBaseLayer = mService.mPolicy.windowTypeToLayerLw(a.type)
+ * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ mSubLayer = 0;
+ mAttachedWindow = null;
+ mLayoutAttached = false;
+ mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
+ || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
+ mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
+ mIsFloatingLayer = mIsImWindow || mIsWallpaper;
+ }
+
+ WindowState appWin = this;
+ while (appWin.mAttachedWindow != null) {
+ appWin = mAttachedWindow;
+ }
+ WindowToken appToken = appWin.mToken;
+ while (appToken.appWindowToken == null) {
+ WindowToken parent = mService.mTokenMap.get(appToken.token);
+ if (parent == null || appToken == parent) {
+ break;
+ }
+ appToken = parent;
+ }
+ mRootToken = appToken;
+ mAppToken = appToken.appWindowToken;
+
+ mSurface = null;
+ mRequestedWidth = 0;
+ mRequestedHeight = 0;
+ mLastRequestedWidth = 0;
+ mLastRequestedHeight = 0;
+ mXOffset = 0;
+ mYOffset = 0;
+ mLayer = 0;
+ mAnimLayer = 0;
+ mLastLayer = 0;
+ mInputWindowHandle = new InputWindowHandle(
+ mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
+ }
+
+ void attach() {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
+ + ", list=" + mToken.windows);
+ mSession.windowAddedLocked();
+ }
+
+ public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
+ mHaveFrame = true;
+
+ final Rect container = mContainingFrame;
+ container.set(pf);
+
+ final Rect display = mDisplayFrame;
+ display.set(df);
+
+ if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+ container.intersect(mService.mCompatibleScreenFrame);
+ if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
+ display.intersect(mService.mCompatibleScreenFrame);
+ }
+ }
+
+ final int pw = container.right - container.left;
+ final int ph = container.bottom - container.top;
+
+ int w,h;
+ if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
+ w = mAttrs.width < 0 ? pw : mAttrs.width;
+ h = mAttrs.height< 0 ? ph : mAttrs.height;
+ } else {
+ w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
+ h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
+ }
+
+ if (!mParentFrame.equals(pf)) {
+ //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
+ // + " to " + pf);
+ mParentFrame.set(pf);
+ mContentChanged = true;
+ }
+
+ final Rect content = mContentFrame;
+ content.set(cf);
+
+ final Rect visible = mVisibleFrame;
+ visible.set(vf);
+
+ final Rect frame = mFrame;
+ final int fw = frame.width();
+ final int fh = frame.height();
+
+ //System.out.println("In: w=" + w + " h=" + h + " container=" +
+ // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
+
+ Gravity.apply(mAttrs.gravity, w, h, container,
+ (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
+ (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
+
+ //System.out.println("Out: " + mFrame);
+
+ // Now make sure the window fits in the overall display.
+ Gravity.applyDisplay(mAttrs.gravity, df, frame);
+
+ // Make sure the content and visible frames are inside of the
+ // final window frame.
+ if (content.left < frame.left) content.left = frame.left;
+ if (content.top < frame.top) content.top = frame.top;
+ if (content.right > frame.right) content.right = frame.right;
+ if (content.bottom > frame.bottom) content.bottom = frame.bottom;
+ if (visible.left < frame.left) visible.left = frame.left;
+ if (visible.top < frame.top) visible.top = frame.top;
+ if (visible.right > frame.right) visible.right = frame.right;
+ if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
+
+ final Rect contentInsets = mContentInsets;
+ contentInsets.left = content.left-frame.left;
+ contentInsets.top = content.top-frame.top;
+ contentInsets.right = frame.right-content.right;
+ contentInsets.bottom = frame.bottom-content.bottom;
+
+ final Rect visibleInsets = mVisibleInsets;
+ visibleInsets.left = visible.left-frame.left;
+ visibleInsets.top = visible.top-frame.top;
+ visibleInsets.right = frame.right-visible.right;
+ visibleInsets.bottom = frame.bottom-visible.bottom;
+
+ if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
+ mService.updateWallpaperOffsetLocked(this, mService.mDisplay.getWidth(),
+ mService.mDisplay.getHeight(), false);
+ }
+
+ if (WindowManagerService.localLOGV) {
+ //if ("com.google.android.youtube".equals(mAttrs.packageName)
+ // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+ Slog.v(WindowManagerService.TAG, "Resolving (mRequestedWidth="
+ + mRequestedWidth + ", mRequestedheight="
+ + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+ + "): frame=" + mFrame.toShortString()
+ + " ci=" + contentInsets.toShortString()
+ + " vi=" + visibleInsets.toShortString());
+ //}
+ }
+ }
+
+ public Rect getFrameLw() {
+ return mFrame;
+ }
+
+ public Rect getShownFrameLw() {
+ return mShownFrame;
+ }
+
+ public Rect getDisplayFrameLw() {
+ return mDisplayFrame;
+ }
+
+ public Rect getContentFrameLw() {
+ return mContentFrame;
+ }
+
+ public Rect getVisibleFrameLw() {
+ return mVisibleFrame;
+ }
+
+ public boolean getGivenInsetsPendingLw() {
+ return mGivenInsetsPending;
+ }
+
+ public Rect getGivenContentInsetsLw() {
+ return mGivenContentInsets;
+ }
+
+ public Rect getGivenVisibleInsetsLw() {
+ return mGivenVisibleInsets;
+ }
+
+ public WindowManager.LayoutParams getAttrs() {
+ return mAttrs;
+ }
+
+ public int getSurfaceLayer() {
+ return mLayer;
+ }
+
+ public IApplicationToken getAppToken() {
+ return mAppToken != null ? mAppToken.appToken : null;
+ }
+
+ public long getInputDispatchingTimeoutNanos() {
+ return mAppToken != null
+ ? mAppToken.inputDispatchingTimeoutNanos
+ : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ }
+
+ public boolean hasAppShownWindows() {
+ return mAppToken != null ? mAppToken.firstWindowDrawn : false;
+ }
+
+ public void setAnimation(Animation anim) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+ mAnimating = false;
+ mLocalAnimating = false;
+ mAnimation = anim;
+ mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
+ mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
+ }
+
+ public void clearAnimation() {
+ if (mAnimation != null) {
+ mAnimating = true;
+ mLocalAnimating = false;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ }
+
+ Surface createSurfaceLocked() {
+ if (mSurface == null) {
+ mReportDestroySurface = false;
+ mSurfacePendingDestroy = false;
+ mDrawPending = true;
+ mCommitDrawPending = false;
+ mReadyToShow = false;
+ if (mAppToken != null) {
+ mAppToken.allDrawn = false;
+ }
+
+ int flags = 0;
+
+ if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ flags |= Surface.SECURE;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
+ WindowManagerService.TAG, "Creating surface in session "
+ + mSession.mSurfaceSession + " window " + this
+ + " w=" + mFrame.width()
+ + " h=" + mFrame.height() + " format="
+ + mAttrs.format + " flags=" + flags);
+
+ int w = mFrame.width();
+ int h = mFrame.height();
+ if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+ // for a scaled surface, we always want the requested
+ // size.
+ w = mRequestedWidth;
+ h = mRequestedHeight;
+ }
+
+ // Something is wrong and SurfaceFlinger will not like this,
+ // try to revert to sane values
+ if (w <= 0) w = 1;
+ if (h <= 0) h = 1;
+
+ mSurfaceShown = false;
+ mSurfaceLayer = 0;
+ mSurfaceAlpha = 1;
+ mSurfaceX = 0;
+ mSurfaceY = 0;
+ mSurfaceW = w;
+ mSurfaceH = h;
+ try {
+ final boolean isHwAccelerated = (mAttrs.flags &
+ WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
+ final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
+ if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
+ flags |= Surface.OPAQUE;
+ }
+ mSurface = new Surface(
+ mSession.mSurfaceSession, mSession.mPid,
+ mAttrs.getTitle().toString(),
+ 0, w, h, format, flags);
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " CREATE SURFACE "
+ + mSurface + " IN SESSION "
+ + mSession.mSurfaceSession
+ + ": pid=" + mSession.mPid + " format="
+ + mAttrs.format + " flags=0x"
+ + Integer.toHexString(flags)
+ + " / " + this);
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface");
+ mService.reclaimSomeSurfaceMemoryLocked(this, "create");
+ return null;
+ } catch (Exception e) {
+ Slog.e(WindowManagerService.TAG, "Exception creating surface", e);
+ return null;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Got surface: " + mSurface
+ + ", set left=" + mFrame.left + " top=" + mFrame.top
+ + ", animLayer=" + mAnimLayer);
+ if (WindowManagerService.SHOW_TRANSACTIONS) {
+ Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
+ WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
+ mFrame.width() + "x" + mFrame.height() + "), layer=" +
+ mAnimLayer + " HIDE", null);
+ }
+ Surface.openTransaction();
+ try {
+ try {
+ mSurfaceX = mFrame.left + mXOffset;
+ mSurfaceY = mFrame.top + mYOffset;
+ mSurface.setPosition(mSurfaceX, mSurfaceY);
+ mSurfaceLayer = mAnimLayer;
+ mSurface.setLayer(mAnimLayer);
+ mSurfaceShown = false;
+ mSurface.hide();
+ if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null);
+ mSurface.setFlags(Surface.SURFACE_DITHER,
+ Surface.SURFACE_DITHER);
+ }
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e);
+ mService.reclaimSomeSurfaceMemoryLocked(this, "create-init");
+ }
+ mLastHidden = true;
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
+ }
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Created surface " + this);
+ }
+ return mSurface;
+ }
+
+ void destroySurfaceLocked() {
+ if (mAppToken != null && this == mAppToken.startingWindow) {
+ mAppToken.startingDisplayed = false;
+ }
+
+ if (mSurface != null) {
+ mDrawPending = false;
+ mCommitDrawPending = false;
+ mReadyToShow = false;
+
+ int i = mChildWindows.size();
+ while (i > 0) {
+ i--;
+ WindowState c = mChildWindows.get(i);
+ c.mAttachedHidden = true;
+ }
+
+ if (mReportDestroySurface) {
+ mReportDestroySurface = false;
+ mSurfacePendingDestroy = true;
+ try {
+ mClient.dispatchGetNewSurface();
+ // We'll really destroy on the next time around.
+ return;
+ } catch (RemoteException e) {
+ }
+ }
+
+ try {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
+ + mSurface + ", session " + mSession, e);
+ }
+ if (WindowManagerService.SHOW_TRANSACTIONS) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DESTROY", e);
+ }
+ mSurface.destroy();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
+ + " surface " + mSurface + " session " + mSession
+ + ": " + e.toString());
+ }
+
+ mSurfaceShown = false;
+ mSurface = null;
+ }
+ }
+
+ boolean finishDrawingLocked() {
+ if (mDrawPending) {
+ if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
+ WindowManagerService.TAG, "finishDrawingLocked: " + mSurface);
+ mCommitDrawPending = true;
+ mDrawPending = false;
+ return true;
+ }
+ return false;
+ }
+
+ // This must be called while inside a transaction.
+ boolean commitFinishDrawingLocked(long currentTime) {
+ //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
+ if (!mCommitDrawPending) {
+ return false;
+ }
+ mCommitDrawPending = false;
+ mReadyToShow = true;
+ final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
+ final AppWindowToken atoken = mAppToken;
+ if (atoken == null || atoken.allDrawn || starting) {
+ performShowLocked();
+ }
+ return true;
+ }
+
+ // This must be called while inside a transaction.
+ boolean performShowLocked() {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.v(WindowManagerService.TAG, "performShow on " + this
+ + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
+ + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
+ }
+ if (mReadyToShow && isReadyForDisplay()) {
+ if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this,
+ "SHOW (performShowLocked)", null);
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
+ + " during animation: policyVis=" + mPolicyVisibility
+ + " attHidden=" + mAttachedHidden
+ + " tok.hiddenRequested="
+ + (mAppToken != null ? mAppToken.hiddenRequested : false)
+ + " tok.hidden="
+ + (mAppToken != null ? mAppToken.hidden : false)
+ + " animating=" + mAnimating
+ + " tok animating="
+ + (mAppToken != null ? mAppToken.animating : false));
+ if (!mService.showSurfaceRobustlyLocked(this)) {
+ return false;
+ }
+ mLastAlpha = -1;
+ mHasDrawn = true;
+ mLastHidden = false;
+ mReadyToShow = false;
+ mService.enableScreenIfNeededLocked();
+
+ mService.applyEnterAnimationLocked(this);
+
+ int i = mChildWindows.size();
+ while (i > 0) {
+ i--;
+ WindowState c = mChildWindows.get(i);
+ if (c.mAttachedHidden) {
+ c.mAttachedHidden = false;
+ if (c.mSurface != null) {
+ c.performShowLocked();
+ // It hadn't been shown, which means layout not
+ // performed on it, so now we want to make sure to
+ // do a layout. If called from within the transaction
+ // loop, this will cause it to restart with a new
+ // layout.
+ mService.mLayoutNeeded = true;
+ }
+ }
+ }
+
+ if (mAttrs.type != TYPE_APPLICATION_STARTING
+ && mAppToken != null) {
+ mAppToken.firstWindowDrawn = true;
+
+ if (mAppToken.startingData != null) {
+ if (WindowManagerService.DEBUG_STARTING_WINDOW || WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
+ "Finish starting " + mToken
+ + ": first real window is shown, no animation");
+ // If this initial window is animating, stop it -- we
+ // will do an animation to reveal it from behind the
+ // starting window, so there is no need for it to also
+ // be doing its own stuff.
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ // Make sure we clean up the animation.
+ mAnimating = true;
+ }
+ mService.mFinishedStarting.add(mAppToken);
+ mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+ }
+ mAppToken.updateReportedVisibilityLocked();
+ }
+ }
+ return true;
+ }
+
+ // This must be called while inside a transaction. Returns true if
+ // there is more animation to run.
+ boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+ if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) {
+ // We will run animations as long as the display isn't frozen.
+
+ if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
+ mHasTransformation = true;
+ mHasLocalTransformation = true;
+ if (!mLocalAnimating) {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Starting animation in " + this +
+ " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
+ " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
+ mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
+ mAnimation.setStartTime(currentTime);
+ mLocalAnimating = true;
+ mAnimating = true;
+ }
+ mTransformation.clear();
+ final boolean more = mAnimation.getTransformation(
+ currentTime, mTransformation);
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Stepped animation in " + this +
+ ": more=" + more + ", xform=" + mTransformation);
+ if (more) {
+ // we're not done!
+ return true;
+ }
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Finished animation in " + this +
+ " @ " + currentTime);
+
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ //WindowManagerService.this.dump();
+ }
+ mHasLocalTransformation = false;
+ if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
+ && mAppToken.animation != null) {
+ // When our app token is animating, we kind-of pretend like
+ // we are as well. Note the mLocalAnimating mAnimationIsEntrance
+ // part of this check means that we will only do this if
+ // our window is not currently exiting, or it is not
+ // locally animating itself. The idea being that one that
+ // is exiting and doing a local animation should be removed
+ // once that animation is done.
+ mAnimating = true;
+ mHasTransformation = true;
+ mTransformation.clear();
+ return false;
+ } else if (mHasTransformation) {
+ // Little trick to get through the path below to act like
+ // we have finished an animation.
+ mAnimating = true;
+ } else if (isAnimating()) {
+ mAnimating = true;
+ }
+ } else if (mAnimation != null) {
+ // If the display is frozen, and there is a pending animation,
+ // clear it and make sure we run the cleanup code.
+ mAnimating = true;
+ mLocalAnimating = true;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+
+ if (!mAnimating && !mLocalAnimating) {
+ return false;
+ }
+
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting
+ + ", reportedVisible="
+ + (mAppToken != null ? mAppToken.reportedVisible : false));
+
+ mAnimating = false;
+ mLocalAnimating = false;
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ mAnimLayer = mLayer;
+ if (mIsImWindow) {
+ mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
+ } else if (mIsWallpaper) {
+ mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+ }
+ if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
+ + " anim layer: " + mAnimLayer);
+ mHasTransformation = false;
+ mHasLocalTransformation = false;
+ if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
+ + mPolicyVisibilityAfterAnim);
+ }
+ mPolicyVisibility = mPolicyVisibilityAfterAnim;
+ if (!mPolicyVisibility) {
+ if (mService.mCurrentFocus == this) {
+ mService.mFocusMayChange = true;
+ }
+ // Window is no longer visible -- make sure if we were waiting
+ // for it to be displayed before enabling the display, that
+ // we allow the display to be enabled now.
+ mService.enableScreenIfNeededLocked();
+ }
+ }
+ mTransformation.clear();
+ if (mHasDrawn
+ && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
+ && mAppToken != null
+ && mAppToken.firstWindowDrawn
+ && mAppToken.startingData != null) {
+ if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
+ + mToken + ": first real window done animating");
+ mService.mFinishedStarting.add(mAppToken);
+ mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+ }
+
+ finishExit();
+
+ if (mAppToken != null) {
+ mAppToken.updateReportedVisibilityLocked();
+ }
+
+ return false;
+ }
+
+ void finishExit() {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "finishExit in " + this
+ + ": exiting=" + mExiting
+ + " remove=" + mRemoveOnExit
+ + " windowAnimating=" + isWindowAnimating());
+
+ final int N = mChildWindows.size();
+ for (int i=0; i<N; i++) {
+ mChildWindows.get(i).finishExit();
+ }
+
+ if (!mExiting) {
+ return;
+ }
+
+ if (isWindowAnimating()) {
+ return;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Exit animation finished in " + this
+ + ": remove=" + mRemoveOnExit);
+ if (mSurface != null) {
+ mService.mDestroySurface.add(this);
+ mDestroying = true;
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null);
+ mSurfaceShown = false;
+ try {
+ mSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
+ }
+ mLastHidden = true;
+ }
+ mExiting = false;
+ if (mRemoveOnExit) {
+ mService.mPendingRemove.add(this);
+ mRemoveOnExit = false;
+ }
+ }
+
+ boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ if (dsdx < .99999f || dsdx > 1.00001f) return false;
+ if (dtdy < .99999f || dtdy > 1.00001f) return false;
+ if (dtdx < -.000001f || dtdx > .000001f) return false;
+ if (dsdy < -.000001f || dsdy > .000001f) return false;
+ return true;
+ }
+
+ void computeShownFrameLocked() {
+ final boolean selfTransformation = mHasLocalTransformation;
+ Transformation attachedTransformation =
+ (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
+ ? mAttachedWindow.mTransformation : null;
+ Transformation appTransformation =
+ (mAppToken != null && mAppToken.hasTransformation)
+ ? mAppToken.transformation : null;
+
+ // Wallpapers are animated based on the "real" window they
+ // are currently targeting.
+ if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
+ && mService.mWallpaperTarget != null) {
+ if (mService.mWallpaperTarget.mHasLocalTransformation &&
+ mService.mWallpaperTarget.mAnimation != null &&
+ !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) {
+ attachedTransformation = mService.mWallpaperTarget.mTransformation;
+ if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
+ Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
+ }
+ }
+ if (mService.mWallpaperTarget.mAppToken != null &&
+ mService.mWallpaperTarget.mAppToken.hasTransformation &&
+ mService.mWallpaperTarget.mAppToken.animation != null &&
+ !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
+ appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
+ if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
+ Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation);
+ }
+ }
+ }
+
+ final boolean screenAnimation = mService.mScreenRotationAnimation != null
+ && mService.mScreenRotationAnimation.isAnimating();
+ if (selfTransformation || attachedTransformation != null
+ || appTransformation != null || screenAnimation) {
+ // cache often used attributes locally
+ final Rect frame = mFrame;
+ final float tmpFloats[] = mService.mTmpFloats;
+ final Matrix tmpMatrix = mTmpMatrix;
+
+ // Compute the desired transformation.
+ tmpMatrix.setTranslate(0, 0);
+ if (selfTransformation) {
+ tmpMatrix.postConcat(mTransformation.getMatrix());
+ }
+ tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
+ if (attachedTransformation != null) {
+ tmpMatrix.postConcat(attachedTransformation.getMatrix());
+ }
+ if (appTransformation != null) {
+ tmpMatrix.postConcat(appTransformation.getMatrix());
+ }
+ if (screenAnimation) {
+ tmpMatrix.postConcat(
+ mService.mScreenRotationAnimation.getEnterTransformation().getMatrix());
+ }
+
+ // "convert" it into SurfaceFlinger's format
+ // (a 2x2 matrix + an offset)
+ // Here we must not transform the position of the surface
+ // since it is already included in the transformation.
+ //Slog.i(TAG, "Transform: " + matrix);
+
+ mHaveMatrix = true;
+ tmpMatrix.getValues(tmpFloats);
+ mDsDx = tmpFloats[Matrix.MSCALE_X];
+ mDtDx = tmpFloats[Matrix.MSKEW_Y];
+ mDsDy = tmpFloats[Matrix.MSKEW_X];
+ mDtDy = tmpFloats[Matrix.MSCALE_Y];
+ int x = (int)tmpFloats[Matrix.MTRANS_X];
+ int y = (int)tmpFloats[Matrix.MTRANS_Y];
+ int w = frame.width();
+ int h = frame.height();
+ mShownFrame.set(x, y, x+w, y+h);
+
+ // Now set the alpha... but because our current hardware
+ // can't do alpha transformation on a non-opaque surface,
+ // turn it off if we are running an animation that is also
+ // transforming since it is more important to have that
+ // animation be smooth.
+ mShownAlpha = mAlpha;
+ if (!mService.mLimitedAlphaCompositing
+ || (!PixelFormat.formatHasAlpha(mAttrs.format)
+ || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
+ && x == frame.left && y == frame.top))) {
+ //Slog.i(TAG, "Applying alpha transform");
+ if (selfTransformation) {
+ mShownAlpha *= mTransformation.getAlpha();
+ }
+ if (attachedTransformation != null) {
+ mShownAlpha *= attachedTransformation.getAlpha();
+ }
+ if (appTransformation != null) {
+ mShownAlpha *= appTransformation.getAlpha();
+ }
+ if (screenAnimation) {
+ mShownAlpha *=
+ mService.mScreenRotationAnimation.getEnterTransformation().getAlpha();
+ }
+ } else {
+ //Slog.i(TAG, "Not applying alpha transform");
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Continuing animation in " + this +
+ ": " + mShownFrame +
+ ", alpha=" + mTransformation.getAlpha());
+ return;
+ }
+
+ mShownFrame.set(mFrame);
+ if (mXOffset != 0 || mYOffset != 0) {
+ mShownFrame.offset(mXOffset, mYOffset);
+ }
+ mShownAlpha = mAlpha;
+ mHaveMatrix = false;
+ mDsDx = 1;
+ mDtDx = 0;
+ mDsDy = 0;
+ mDtDy = 1;
+ }
+
+ /**
+ * Is this window visible? It is not visible if there is no
+ * surface, or we are in the process of running an exit animation
+ * that will remove the surface, or its app token has been hidden.
+ */
+ public boolean isVisibleLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Like {@link #isVisibleLw}, but also counts a window that is currently
+ * "hidden" behind the keyguard as visible. This allows us to apply
+ * things like window flags that impact the keyguard.
+ * XXX I am starting to think we need to have ANOTHER visibility flag
+ * for this "hidden behind keyguard" state rather than overloading
+ * mPolicyVisibility. Ungh.
+ */
+ public boolean isVisibleOrBehindKeyguardLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && !mAttachedHidden
+ && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
+ && !mDrawPending && !mCommitDrawPending
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Is this window visible, ignoring its app token? It is not visible
+ * if there is no surface, or we are in the process of running an exit animation
+ * that will remove the surface.
+ */
+ public boolean isWinVisibleLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested || atoken.animating)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * The same as isVisible(), but follows the current hidden state of
+ * the associated app token, not the pending requested hidden state.
+ */
+ boolean isVisibleNow() {
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && !mRootToken.hidden && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Can this window possibly be a drag/drop target? The test here is
+ * a combination of the above "visible now" with the check that the
+ * Input Manager uses when discarding windows from input consideration.
+ */
+ boolean isPotentialDragTarget() {
+ return isVisibleNow() && (mInputChannel != null) && !mRemoved;
+ }
+
+ /**
+ * Same as isVisible(), but we also count it as visible between the
+ * call to IWindowSession.add() and the first relayout().
+ */
+ boolean isVisibleOrAdding() {
+ final AppWindowToken atoken = mAppToken;
+ return ((mSurface != null && !mReportDestroySurface)
+ || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
+ && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Is this window currently on-screen? It is on-screen either if it
+ * is visible or it is currently running an animation before no longer
+ * being visible.
+ */
+ boolean isOnScreen() {
+ final AppWindowToken atoken = mAppToken;
+ if (atoken != null) {
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && ((!mAttachedHidden && !atoken.hiddenRequested)
+ || mAnimation != null || atoken.animation != null);
+ } else {
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && (!mAttachedHidden || mAnimation != null);
+ }
+ }
+
+ /**
+ * Like isOnScreen(), but we don't return true if the window is part
+ * of a transition that has not yet been started.
+ */
+ boolean isReadyForDisplay() {
+ if (mRootToken.waitingToShow &&
+ mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+ return false;
+ }
+ final AppWindowToken atoken = mAppToken;
+ final boolean animating = atoken != null
+ ? (atoken.animation != null) : false;
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
+ && !mRootToken.hidden)
+ || mAnimation != null || animating);
+ }
+
+ /** Is the window or its container currently animating? */
+ boolean isAnimating() {
+ final WindowState attached = mAttachedWindow;
+ final AppWindowToken atoken = mAppToken;
+ return mAnimation != null
+ || (attached != null && attached.mAnimation != null)
+ || (atoken != null &&
+ (atoken.animation != null
+ || atoken.inPendingTransaction));
+ }
+
+ /** Is this window currently animating? */
+ boolean isWindowAnimating() {
+ return mAnimation != null;
+ }
+
+ /**
+ * Like isOnScreen, but returns false if the surface hasn't yet
+ * been drawn.
+ */
+ public boolean isDisplayedLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && !mDrawPending && !mCommitDrawPending
+ && ((!mAttachedHidden &&
+ (atoken == null || !atoken.hiddenRequested))
+ || mAnimating);
+ }
+
+ /**
+ * Returns true if the window has a surface that it has drawn a
+ * complete UI in to.
+ */
+ public boolean isDrawnLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && !mDestroying
+ && !mDrawPending && !mCommitDrawPending;
+ }
+
+ /**
+ * Return true if the window is opaque and fully drawn. This indicates
+ * it may obscure windows behind it.
+ */
+ boolean isOpaqueDrawn() {
+ return (mAttrs.format == PixelFormat.OPAQUE
+ || mAttrs.type == TYPE_WALLPAPER)
+ && mSurface != null && mAnimation == null
+ && (mAppToken == null || mAppToken.animation == null)
+ && !mDrawPending && !mCommitDrawPending;
+ }
+
+ /**
+ * Return whether this window is wanting to have a translation
+ * animation applied to it for an in-progress move. (Only makes
+ * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
+ */
+ boolean shouldAnimateMove() {
+ return mContentChanged && !mExiting && !mLastHidden && !mService.mDisplayFrozen
+ && (mFrame.top != mLastFrame.top
+ || mFrame.left != mLastFrame.left)
+ && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
+ && mService.mPolicy.isScreenOn();
+ }
+
+ boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
+ return
+ // only if the application is requesting compatible window
+ (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
+ // only if it's visible
+ mHasDrawn && mViewVisibility == View.VISIBLE &&
+ // and only if the application fills the compatible screen
+ mFrame.left <= mService.mCompatibleScreenFrame.left &&
+ mFrame.top <= mService.mCompatibleScreenFrame.top &&
+ mFrame.right >= mService.mCompatibleScreenFrame.right &&
+ mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
+ }
+
+ boolean isFullscreen(int screenWidth, int screenHeight) {
+ return mFrame.left <= 0 && mFrame.top <= 0 &&
+ mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
+ }
+
+ void removeLocked() {
+ disposeInputChannel();
+
+ if (mAttachedWindow != null) {
+ if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
+ mAttachedWindow.mChildWindows.remove(this);
+ }
+ destroySurfaceLocked();
+ mSession.windowRemovedLocked();
+ try {
+ mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (RuntimeException e) {
+ // Ignore if it has already been removed (usually because
+ // we are doing this as part of processing a death note.)
+ }
+ }
+
+ void disposeInputChannel() {
+ if (mInputChannel != null) {
+ mService.mInputManager.unregisterInputChannel(mInputChannel);
+
+ mInputChannel.dispose();
+ mInputChannel = null;
+ }
+ }
+
+ private class DeathRecipient implements IBinder.DeathRecipient {
+ public void binderDied() {
+ try {
+ synchronized(mService.mWindowMap) {
+ WindowState win = mService.windowForClientLocked(mSession, mClient, false);
+ Slog.i(WindowManagerService.TAG, "WIN DEATH: " + win);
+ if (win != null) {
+ mService.removeWindowLocked(mSession, win);
+ }
+ }
+ } catch (IllegalArgumentException ex) {
+ // This will happen if the window has already been
+ // removed.
+ }
+ }
+ }
+
+ /** Returns true if this window desires key events. */
+ public final boolean canReceiveKeys() {
+ return isVisibleOrAdding()
+ && (mViewVisibility == View.VISIBLE)
+ && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
+ }
+
+ public boolean hasDrawnLw() {
+ return mHasDrawn;
+ }
+
+ public boolean showLw(boolean doAnimation) {
+ return showLw(doAnimation, true);
+ }
+
+ boolean showLw(boolean doAnimation, boolean requestAnim) {
+ if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
+ return false;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this);
+ if (doAnimation) {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
+ + mPolicyVisibility + " mAnimation=" + mAnimation);
+ if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+ doAnimation = false;
+ } else if (mPolicyVisibility && mAnimation == null) {
+ // Check for the case where we are currently visible and
+ // not animating; we do not want to do animation at such a
+ // point to become visible when we already are.
+ doAnimation = false;
+ }
+ }
+ mPolicyVisibility = true;
+ mPolicyVisibilityAfterAnim = true;
+ if (doAnimation) {
+ mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
+ }
+ if (requestAnim) {
+ mService.requestAnimationLocked(0);
+ }
+ return true;
+ }
+
+ public boolean hideLw(boolean doAnimation) {
+ return hideLw(doAnimation, true);
+ }
+
+ boolean hideLw(boolean doAnimation, boolean requestAnim) {
+ if (doAnimation) {
+ if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+ doAnimation = false;
+ }
+ }
+ boolean current = doAnimation ? mPolicyVisibilityAfterAnim
+ : mPolicyVisibility;
+ if (!current) {
+ return false;
+ }
+ if (doAnimation) {
+ mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
+ if (mAnimation == null) {
+ doAnimation = false;
+ }
+ }
+ if (doAnimation) {
+ mPolicyVisibilityAfterAnim = false;
+ } else {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility false: " + this);
+ mPolicyVisibilityAfterAnim = false;
+ mPolicyVisibility = false;
+ // Window is no longer visible -- make sure if we were waiting
+ // for it to be displayed before enabling the display, that
+ // we allow the display to be enabled now.
+ mService.enableScreenIfNeededLocked();
+ if (mService.mCurrentFocus == this) {
+ mService.mFocusMayChange = true;
+ }
+ }
+ if (requestAnim) {
+ mService.requestAnimationLocked(0);
+ }
+ return true;
+ }
+
+ public void getTouchableRegion(Region outRegion) {
+ final Rect frame = mFrame;
+ switch (mTouchableInsets) {
+ default:
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
+ outRegion.set(frame);
+ break;
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
+ final Rect inset = mGivenContentInsets;
+ outRegion.set(
+ frame.left + inset.left, frame.top + inset.top,
+ frame.right - inset.right, frame.bottom - inset.bottom);
+ break;
+ }
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
+ final Rect inset = mGivenVisibleInsets;
+ outRegion.set(
+ frame.left + inset.left, frame.top + inset.top,
+ frame.right - inset.right, frame.bottom - inset.bottom);
+ break;
+ }
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
+ final Region givenTouchableRegion = mGivenTouchableRegion;
+ outRegion.set(givenTouchableRegion);
+ outRegion.translate(frame.left, frame.top);
+ break;
+ }
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mSession="); pw.print(mSession);
+ pw.print(" mClient="); pw.println(mClient.asBinder());
+ pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
+ if (mAttachedWindow != null || mLayoutAttached) {
+ pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
+ pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
+ }
+ if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
+ pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
+ pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
+ pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
+ pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
+ }
+ pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
+ pw.print(" mSubLayer="); pw.print(mSubLayer);
+ pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
+ pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
+ : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
+ pw.print("="); pw.print(mAnimLayer);
+ pw.print(" mLastLayer="); pw.println(mLastLayer);
+ if (mSurface != null) {
+ pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
+ pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
+ pw.print(" layer="); pw.print(mSurfaceLayer);
+ pw.print(" alpha="); pw.print(mSurfaceAlpha);
+ pw.print(" rect=("); pw.print(mSurfaceX);
+ pw.print(","); pw.print(mSurfaceY);
+ pw.print(") "); pw.print(mSurfaceW);
+ pw.print(" x "); pw.println(mSurfaceH);
+ }
+ pw.print(prefix); pw.print("mToken="); pw.println(mToken);
+ pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
+ if (mAppToken != null) {
+ pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
+ }
+ if (mTargetAppToken != null) {
+ pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
+ }
+ pw.print(prefix); pw.print("mViewVisibility=0x");
+ pw.print(Integer.toHexString(mViewVisibility));
+ pw.print(" mLastHidden="); pw.print(mLastHidden);
+ pw.print(" mHaveFrame="); pw.print(mHaveFrame);
+ pw.print(" mObscured="); pw.println(mObscured);
+ if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
+ pw.print(prefix); pw.print("mPolicyVisibility=");
+ pw.print(mPolicyVisibility);
+ pw.print(" mPolicyVisibilityAfterAnim=");
+ pw.print(mPolicyVisibilityAfterAnim);
+ pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
+ }
+ if (!mRelayoutCalled) {
+ pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
+ }
+ pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
+ pw.print(" h="); pw.print(mRequestedHeight);
+ pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
+ if (mXOffset != 0 || mYOffset != 0) {
+ pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
+ pw.print(" y="); pw.println(mYOffset);
+ }
+ pw.print(prefix); pw.print("mGivenContentInsets=");
+ mGivenContentInsets.printShortString(pw);
+ pw.print(" mGivenVisibleInsets=");
+ mGivenVisibleInsets.printShortString(pw);
+ pw.println();
+ if (mTouchableInsets != 0 || mGivenInsetsPending) {
+ pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
+ pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
+ }
+ pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
+ pw.print(prefix); pw.print("mShownFrame=");
+ mShownFrame.printShortString(pw);
+ pw.print(" last="); mLastShownFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
+ pw.print(" last="); mLastFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContainingFrame=");
+ mContainingFrame.printShortString(pw);
+ pw.print(" mParentFrame=");
+ mParentFrame.printShortString(pw);
+ pw.print(" mDisplayFrame=");
+ mDisplayFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
+ pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
+ pw.print(" last="); mLastContentInsets.printShortString(pw);
+ pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
+ pw.print(" last="); mLastVisibleInsets.printShortString(pw);
+ pw.println();
+ if (mAnimating || mLocalAnimating || mAnimationIsEntrance
+ || mAnimation != null) {
+ pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
+ pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
+ pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
+ pw.print(" mAnimation="); pw.println(mAnimation);
+ }
+ if (mHasTransformation || mHasLocalTransformation) {
+ pw.print(prefix); pw.print("XForm: has=");
+ pw.print(mHasTransformation);
+ pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
+ pw.print(" "); mTransformation.printShortString(pw);
+ pw.println();
+ }
+ if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
+ pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
+ pw.print(" mAlpha="); pw.print(mAlpha);
+ pw.print(" mLastAlpha="); pw.println(mLastAlpha);
+ }
+ if (mHaveMatrix) {
+ pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
+ pw.print(" mDtDx="); pw.print(mDtDx);
+ pw.print(" mDsDy="); pw.print(mDsDy);
+ pw.print(" mDtDy="); pw.println(mDtDy);
+ }
+ pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
+ pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
+ pw.print(" mReadyToShow="); pw.print(mReadyToShow);
+ pw.print(" mHasDrawn="); pw.println(mHasDrawn);
+ if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
+ pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
+ pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
+ pw.print(" mDestroying="); pw.print(mDestroying);
+ pw.print(" mRemoved="); pw.println(mRemoved);
+ }
+ if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
+ pw.print(prefix); pw.print("mOrientationChanging=");
+ pw.print(mOrientationChanging);
+ pw.print(" mAppFreezing="); pw.print(mAppFreezing);
+ pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
+ }
+ if (mHScale != 1 || mVScale != 1) {
+ pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
+ pw.print(" mVScale="); pw.println(mVScale);
+ }
+ if (mWallpaperX != -1 || mWallpaperY != -1) {
+ pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
+ pw.print(" mWallpaperY="); pw.println(mWallpaperY);
+ }
+ if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
+ pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
+ pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
+ }
+ }
+
+ String makeInputChannelName() {
+ return Integer.toHexString(System.identityHashCode(this))
+ + " " + mAttrs.getTitle();
+ }
+
+ @Override
+ public String toString() {
+ if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
+ || mWasPaused != mToken.paused) {
+ mLastTitle = mAttrs.getTitle();
+ mWasPaused = mToken.paused;
+ mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+ + " " + mLastTitle + " paused=" + mWasPaused + "}";
+ }
+ return mStringNameCache;
+ }
+}
\ No newline at end of file
diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java
new file mode 100644
index 0000000..3cd256e
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowToken.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.os.IBinder;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Container of a set of related windows in the window manager. Often this
+ * is an AppWindowToken, which is the handle for an Activity that it uses
+ * to display windows. For nested windows, there is a WindowToken created for
+ * the parent window to manage its children.
+ */
+class WindowToken {
+ // The window manager!
+ final WindowManagerService service;
+
+ // The actual token.
+ final IBinder token;
+
+ // The type of window this token is for, as per WindowManager.LayoutParams.
+ final int windowType;
+
+ // Set if this token was explicitly added by a client, so should
+ // not be removed when all windows are removed.
+ final boolean explicit;
+
+ // For printing.
+ String stringName;
+
+ // If this is an AppWindowToken, this is non-null.
+ AppWindowToken appWindowToken;
+
+ // All of the windows associated with this token.
+ final ArrayList<WindowState> windows = new ArrayList<WindowState>();
+
+ // Is key dispatching paused for this token?
+ boolean paused = false;
+
+ // Should this token's windows be hidden?
+ boolean hidden;
+
+ // Temporary for finding which tokens no longer have visible windows.
+ boolean hasVisible;
+
+ // Set to true when this token is in a pending transaction where it
+ // will be shown.
+ boolean waitingToShow;
+
+ // Set to true when this token is in a pending transaction where it
+ // will be hidden.
+ boolean waitingToHide;
+
+ // Set to true when this token is in a pending transaction where its
+ // windows will be put to the bottom of the list.
+ boolean sendingToBottom;
+
+ // Set to true when this token is in a pending transaction where its
+ // windows will be put to the top of the list.
+ boolean sendingToTop;
+
+ WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) {
+ service = _service;
+ token = _token;
+ windowType = type;
+ explicit = _explicit;
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("token="); pw.println(token);
+ pw.print(prefix); pw.print("windows="); pw.println(windows);
+ pw.print(prefix); pw.print("windowType="); pw.print(windowType);
+ pw.print(" hidden="); pw.print(hidden);
+ pw.print(" hasVisible="); pw.println(hasVisible);
+ if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
+ pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
+ pw.print(" waitingToHide="); pw.print(waitingToHide);
+ pw.print(" sendingToBottom="); pw.print(sendingToBottom);
+ pw.print(" sendingToTop="); pw.println(sendingToTop);
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (stringName == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("WindowToken{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" token="); sb.append(token); sb.append('}');
+ stringName = sb.toString();
+ }
+ return stringName;
+ }
+}
\ No newline at end of file
diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/jni/com_android_server_AlarmManagerService.cpp
index 0e162bd..aa8c9b3 100644
--- a/services/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/jni/com_android_server_AlarmManagerService.cpp
@@ -33,7 +33,7 @@
#include <errno.h>
#include <unistd.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#include <linux/android_alarm.h>
#endif
@@ -42,7 +42,7 @@
static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timezone tz;
tz.tz_minuteswest = minswest;
@@ -64,7 +64,7 @@
static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
return open("/dev/alarm", O_RDWR);
#else
return -1;
@@ -73,14 +73,14 @@
static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
close(fd);
#endif
}
static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timespec ts;
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds;
@@ -95,7 +95,7 @@
static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
int result = 0;
do
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index d4513e9..98d0d92 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -33,7 +33,7 @@
#include <unistd.h>
#include <dirent.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#endif
diff --git a/services/jni/com_android_server_InputApplication.cpp b/services/jni/com_android_server_InputApplication.cpp
index a46a162..e64ec4e 100644
--- a/services/jni/com_android_server_InputApplication.cpp
+++ b/services/jni/com_android_server_InputApplication.cpp
@@ -77,11 +77,11 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplication(JNIEnv* env) {
- FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
+ FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/wm/InputApplication");
GET_FIELD_ID(gInputApplicationClassInfo.inputApplicationHandle,
gInputApplicationClassInfo.clazz,
- "inputApplicationHandle", "Lcom/android/server/InputApplicationHandle;");
+ "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
"name", "Ljava/lang/String;");
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_InputApplicationHandle.cpp
index ab82635..3a1214f 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_InputApplicationHandle.cpp
@@ -106,11 +106,11 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplicationHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputApplicationHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputApplicationHandle",
gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputApplicationHandleClassInfo.clazz, "com/android/server/InputApplicationHandle");
+ FIND_CLASS(gInputApplicationHandleClassInfo.clazz, "com/android/server/wm/InputApplicationHandle");
GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, gInputApplicationHandleClassInfo.clazz,
"ptr", "I");
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 5b329bb..0a50ff8 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -87,7 +87,6 @@
jfieldID mName;
jfieldID mSources;
jfieldID mKeyboardType;
- jfieldID mMotionRanges;
} gInputDeviceClassInfo;
static struct {
@@ -1080,7 +1079,7 @@
static JNINativeMethod gInputManagerMethods[] = {
/* name, signature, funcPtr */
- { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
+ { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;)V",
(void*) android_server_InputManager_nativeInit },
{ "nativeStart", "()V",
(void*) android_server_InputManager_nativeStart },
@@ -1097,15 +1096,15 @@
{ "nativeHasKeys", "(II[I[Z)Z",
(void*) android_server_InputManager_nativeHasKeys },
{ "nativeRegisterInputChannel",
- "(Landroid/view/InputChannel;Lcom/android/server/InputWindowHandle;Z)V",
+ "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
(void*) android_server_InputManager_nativeRegisterInputChannel },
{ "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
(void*) android_server_InputManager_nativeUnregisterInputChannel },
{ "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
(void*) android_server_InputManager_nativeInjectInputEvent },
- { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
+ { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
(void*) android_server_InputManager_nativeSetInputWindows },
- { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
+ { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
(void*) android_server_InputManager_nativeSetFocusedApplication },
{ "nativeSetInputDispatchMode", "(ZZ)V",
(void*) android_server_InputManager_nativeSetInputDispatchMode },
@@ -1135,13 +1134,13 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputManager(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
gInputManagerMethods, NELEM(gInputManagerMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
// Callbacks
- FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
+ FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
"notifyConfigurationChanged", "(J)V");
@@ -1150,22 +1149,22 @@
"notifyLidSwitchChanged", "(JZ)V");
GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
- "notifyInputChannelBroken", "(Lcom/android/server/InputWindowHandle;)V");
+ "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
"notifyANR",
- "(Lcom/android/server/InputApplicationHandle;Lcom/android/server/InputWindowHandle;)J");
+ "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
"interceptKeyBeforeDispatching",
- "(Lcom/android/server/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
+ "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
"dispatchUnhandledKey",
- "(Lcom/android/server/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
+ "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
"checkInjectEventsPermission", "(II)Z");
@@ -1189,7 +1188,7 @@
"getPointerLayer", "()I");
GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
- "getPointerIcon", "()Lcom/android/server/InputManager$PointerIcon;");
+ "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
// KeyEvent
@@ -1221,9 +1220,6 @@
GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
"mKeyboardType", "I");
- GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
- "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
-
// Configuration
FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
@@ -1239,7 +1235,7 @@
// PointerIcon
- FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/InputManager$PointerIcon");
+ FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
"bitmap", "Landroid/graphics/Bitmap;");
diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp
index 75154567c..8548b47 100644
--- a/services/jni/com_android_server_InputWindow.cpp
+++ b/services/jni/com_android_server_InputWindow.cpp
@@ -144,10 +144,10 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindow(JNIEnv* env) {
- FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
+ FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/wm/InputWindow");
GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, gInputWindowClassInfo.clazz,
- "inputWindowHandle", "Lcom/android/server/InputWindowHandle;");
+ "inputWindowHandle", "Lcom/android/server/wm/InputWindowHandle;");
GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
"inputChannel", "Landroid/view/InputChannel;");
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_InputWindowHandle.cpp
index 4d66212..5b74e43 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_InputWindowHandle.cpp
@@ -116,18 +116,18 @@
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindowHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputWindowHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputWindowHandle",
gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputWindowHandleClassInfo.clazz, "com/android/server/InputWindowHandle");
+ FIND_CLASS(gInputWindowHandleClassInfo.clazz, "com/android/server/wm/InputWindowHandle");
GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, gInputWindowHandleClassInfo.clazz,
"ptr", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
gInputWindowHandleClassInfo.clazz,
- "inputApplicationHandle", "Lcom/android/server/InputApplicationHandle;");
+ "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
return 0;
}
diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp
index ef22111..192daaf 100644
--- a/services/jni/com_android_server_UsbService.cpp
+++ b/services/jni/com_android_server_UsbService.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,13 @@
#include <stdio.h>
#include <asm/byteorder.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/usb/f_accessory.h>
+
+#define DRIVER_NAME "/dev/usb_accessory"
namespace android
{
@@ -164,10 +171,67 @@
gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
}
+static void set_accessory_string(JNIEnv *env, int fd, int cmd, jobjectArray strArray, int index)
+{
+ char buffer[256];
+
+ buffer[0] = 0;
+ int length = ioctl(fd, cmd, buffer);
+ LOGD("ioctl returned %d", length);
+ if (buffer[0]) {
+ jstring obj = env->NewStringUTF(buffer);
+ env->SetObjectArrayElement(strArray, index, obj);
+ env->DeleteLocalRef(obj);
+ }
+}
+
+
+static jobjectArray android_server_UsbService_getAccessoryStrings(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ LOGE("could not open %s", DRIVER_NAME);
+ return NULL;
+ }
+ jclass stringClass = env->FindClass("java/lang/String");
+ jobjectArray strArray = env->NewObjectArray(4, stringClass, NULL);
+ if (!strArray) goto out;
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_MANUFACTURER, strArray, 0);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_MODEL, strArray, 1);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_TYPE, strArray, 2);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_VERSION, strArray, 3);
+
+out:
+ close(fd);
+ return strArray;
+}
+
+static jobject android_server_UsbService_openAccessory(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ LOGE("could not open %s", DRIVER_NAME);
+ return NULL;
+ }
+ jobject fileDescriptor = env->NewObject(gFileDescriptorOffsets.mClass,
+ gFileDescriptorOffsets.mConstructor);
+ if (fileDescriptor != NULL) {
+ env->SetIntField(fileDescriptor, gFileDescriptorOffsets.mDescriptor, fd);
+ } else {
+ return NULL;
+ }
+ return env->NewObject(gParcelFileDescriptorOffsets.mClass,
+ gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
+}
+
static JNINativeMethod method_table[] = {
{ "monitorUsbHostBus", "()V", (void*)android_server_UsbService_monitorUsbHostBus },
{ "nativeOpenDevice", "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;",
(void*)android_server_UsbService_openDevice },
+ { "nativeGetAccessoryStrings", "()[Ljava/lang/String;",
+ (void*)android_server_UsbService_getAccessoryStrings },
+ { "nativeOpenAccessory","()Landroid/os/ParcelFileDescriptor;",
+ (void*)android_server_UsbService_openAccessory },
};
int register_android_server_UsbService(JNIEnv *env)
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fde8e67..0f7d639 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -142,7 +142,8 @@
sp<LayerBaseClient::Surface> Layer::createSurface() const
{
- return mSurface;
+ sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
+ return sur;
}
status_t Layer::ditch()
@@ -152,9 +153,6 @@
// the layer is not on screen anymore. free as much resources as possible
mFreezeLock.clear();
- // Free our own reference to ISurface
- mSurface.clear();
-
Mutex::Autolock _l(mLock);
mWidth = mHeight = 0;
return NO_ERROR;
@@ -202,7 +200,6 @@
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
mNeedsDithering = layerRedsize > displayRedSize;
- mSurface = new SurfaceLayer(mFlinger, this);
return NO_ERROR;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d9a8be3..2b38414 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -213,7 +213,6 @@
ClientRef mUserClientRef;
// constants
- sp<Surface> mSurface;
PixelFormat mFormat;
const GLExtensions& mGLExtensions;
bool mNeedsBlending;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 86057f8..6025ed4 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -540,7 +540,9 @@
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client)
- : LayerBase(flinger, display), mClientRef(client),
+ : LayerBase(flinger, display),
+ mHasSurface(false),
+ mClientRef(client),
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
}
@@ -557,12 +559,13 @@
{
sp<Surface> s;
Mutex::Autolock _l(mLock);
- s = mClientSurface.promote();
- if (s == 0) {
- s = createSurface();
- mClientSurface = s;
- mClientSurfaceBinder = s->asBinder();
- }
+
+ LOG_ALWAYS_FATAL_IF(mHasSurface,
+ "LayerBaseClient::getSurface() has already been called");
+
+ mHasSurface = true;
+ s = createSurface();
+ mClientSurfaceBinder = s->asBinder();
return s;
}
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 184edd7..bfe92e6 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -337,7 +337,7 @@
private:
mutable Mutex mLock;
- mutable wp<Surface> mClientSurface;
+ mutable bool mHasSurface;
wp<IBinder> mClientSurfaceBinder;
const wp<Client> mClientRef;
// only read
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index c9e304a..98ab3d1 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -27,7 +27,25 @@
*/
public class SignalStrength implements Parcelable {
- static final String LOG_TAG = "PHONE";
+ private static final String LOG_TAG = "SignalStrength";
+ private static final boolean DBG = false;
+
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_POOR = 1;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_MODERATE = 2;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_GOOD = 3;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_GREAT = 4;
+ /** @hide */
+ public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
+ /** @hide */
+ public static final String[] SIGNAL_STRENGTH_NAMES = {
+ "none", "poor", "moderate", "good", "great"
+ };
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
@@ -36,6 +54,11 @@
private int mEvdoDbm; // This value is the EVDO RSSI value
private int mEvdoEcio; // This value is the EVDO Ec/Io
private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
+ private int mLteSignalStrength;
+ private int mLteRsrp;
+ private int mLteRsrq;
+ private int mLteRssnr;
+ private int mLteCqi;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
@@ -70,6 +93,11 @@
mEvdoDbm = -1;
mEvdoEcio = -1;
mEvdoSnr = -1;
+ mLteSignalStrength = -1;
+ mLteRsrp = -1;
+ mLteRsrq = -1;
+ mLteRssnr = -1;
+ mLteCqi = -1;
isGsm = true;
}
@@ -80,7 +108,9 @@
*/
public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
- int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm) {
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+ boolean gsm) {
mGsmSignalStrength = gsmSignalStrength;
mGsmBitErrorRate = gsmBitErrorRate;
mCdmaDbm = cdmaDbm;
@@ -88,10 +118,28 @@
mEvdoDbm = evdoDbm;
mEvdoEcio = evdoEcio;
mEvdoSnr = evdoSnr;
+ mLteSignalStrength = lteSignalStrength;
+ mLteRsrp = lteRsrp;
+ mLteRsrq = lteRsrq;
+ mLteRssnr = lteRssnr;
+ mLteCqi = lteCqi;
isGsm = gsm;
}
/**
+ * Constructor
+ *
+ * @hide
+ */
+ public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+ int cdmaDbm, int cdmaEcio,
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ boolean gsm) {
+ this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+ evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, gsm);
+ }
+
+ /**
* Copy constructors
*
* @param s Source SignalStrength
@@ -113,6 +161,11 @@
mEvdoDbm = s.mEvdoDbm;
mEvdoEcio = s.mEvdoEcio;
mEvdoSnr = s.mEvdoSnr;
+ mLteSignalStrength = s.mLteSignalStrength;
+ mLteRsrp = s.mLteRsrp;
+ mLteRsrq = s.mLteRsrq;
+ mLteRssnr = s.mLteRssnr;
+ mLteCqi = s.mLteCqi;
isGsm = s.isGsm;
}
@@ -129,6 +182,11 @@
mEvdoDbm = in.readInt();
mEvdoEcio = in.readInt();
mEvdoSnr = in.readInt();
+ mLteSignalStrength = in.readInt();
+ mLteRsrp = in.readInt();
+ mLteRsrq = in.readInt();
+ mLteRssnr = in.readInt();
+ mLteCqi = in.readInt();
isGsm = (in.readInt() != 0);
}
@@ -143,6 +201,11 @@
out.writeInt(mEvdoDbm);
out.writeInt(mEvdoEcio);
out.writeInt(mEvdoSnr);
+ out.writeInt(mLteSignalStrength);
+ out.writeInt(mLteRsrp);
+ out.writeInt(mLteRsrq);
+ out.writeInt(mLteRssnr);
+ out.writeInt(mLteCqi);
out.writeInt(isGsm ? 1 : 0);
}
@@ -218,6 +281,312 @@
}
/**
+ * Get signal level as an int from 0..4
+ *
+ * @hide
+ */
+ public int getLevel() {
+ int level;
+
+ if (isGsm) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ level = getGsmLevel();
+ } else {
+ level = getLteLevel();
+ }
+ } else {
+ int cdmaLevel = getCdmaLevel();
+ int evdoLevel = getEvdoLevel();
+ if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ /* We don't know evdo, use cdma */
+ level = getCdmaLevel();
+ } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ /* We don't know cdma, use evdo */
+ level = getEvdoLevel();
+ } else {
+ /* We know both, use the lowest level */
+ level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
+ }
+ }
+ if (DBG) log("getLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getAsuLevel() {
+ int asuLevel;
+ if (isGsm) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ asuLevel = getGsmAsuLevel();
+ } else {
+ asuLevel = getLteAsuLevel();
+ }
+ } else {
+ int cdmaAsuLevel = getCdmaAsuLevel();
+ int evdoAsuLevel = getEvdoAsuLevel();
+ if (evdoAsuLevel == 0) {
+ /* We don't know evdo use, cdma */
+ asuLevel = cdmaAsuLevel;
+ } else if (cdmaAsuLevel == 0) {
+ /* We don't know cdma use, evdo */
+ asuLevel = evdoAsuLevel;
+ } else {
+ /* We know both, use the lowest level */
+ asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
+ }
+ }
+ if (DBG) log("getAsuLevel=" + asuLevel);
+ return asuLevel;
+ }
+
+ /**
+ * Get the signal strength as dBm
+ *
+ * @hide
+ */
+ public int getDbm() {
+ int dBm;
+
+ if(isGsm()) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ dBm = getGsmDbm();
+ } else {
+ dBm = getLteDbm();
+ }
+ } else {
+ dBm = getCdmaDbm();
+ }
+ if (DBG) log("getDbm=" + dBm);
+ return dBm;
+ }
+
+ /**
+ * Get Gsm signal strength as dBm
+ *
+ * @hide
+ */
+ public int getGsmDbm() {
+ int dBm;
+
+ int gsmSignalStrength = getGsmSignalStrength();
+ int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
+ if (asu != -1) {
+ dBm = -113 + (2 * asu);
+ } else {
+ dBm = -1;
+ }
+ if (DBG) log("getGsmDbm=" + dBm);
+ return dBm;
+ }
+
+ /**
+ * Get gsm as level 0..4
+ *
+ * @hide
+ */
+ public int getGsmLevel() {
+ int level;
+
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int asu = getGsmSignalStrength();
+ if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
+ else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
+ else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
+ else level = SIGNAL_STRENGTH_POOR;
+ if (DBG) log("getGsmLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the gsm signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getGsmAsuLevel() {
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int level = getGsmSignalStrength();
+ if (DBG) log("getGsmAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get cdma as level 0..4
+ *
+ * @hide
+ */
+ public int getCdmaLevel() {
+ final int cdmaDbm = getCdmaDbm();
+ final int cdmaEcio = getCdmaEcio();
+ int levelDbm;
+ int levelEcio;
+
+ if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
+ else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
+ else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
+ else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
+ else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
+ else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
+ else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
+ else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
+ else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
+ if (DBG) log("getCdmaLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the cdma signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getCdmaAsuLevel() {
+ final int cdmaDbm = getCdmaDbm();
+ final int cdmaEcio = getCdmaEcio();
+ int cdmaAsuLevel;
+ int ecioAsuLevel;
+
+ if (cdmaDbm >= -75) cdmaAsuLevel = 16;
+ else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
+ else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
+ else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
+ else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
+ else cdmaAsuLevel = 99;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) ecioAsuLevel = 16;
+ else if (cdmaEcio >= -100) ecioAsuLevel = 8;
+ else if (cdmaEcio >= -115) ecioAsuLevel = 4;
+ else if (cdmaEcio >= -130) ecioAsuLevel = 2;
+ else if (cdmaEcio >= -150) ecioAsuLevel = 1;
+ else ecioAsuLevel = 99;
+
+ int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
+ if (DBG) log("getCdmaAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get Evdo as level 0..4
+ *
+ * @hide
+ */
+ public int getEvdoLevel() {
+ int evdoDbm = getEvdoDbm();
+ int evdoSnr = getEvdoSnr();
+ int levelEvdoDbm;
+ int levelEvdoSnr;
+
+ if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
+ else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
+ else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
+ else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
+ else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
+ else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
+ else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
+ else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
+ else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ if (DBG) log("getEvdoLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the evdo signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getEvdoAsuLevel() {
+ int evdoDbm = getEvdoDbm();
+ int evdoSnr = getEvdoSnr();
+ int levelEvdoDbm;
+ int levelEvdoSnr;
+
+ if (evdoDbm >= -65) levelEvdoDbm = 16;
+ else if (evdoDbm >= -75) levelEvdoDbm = 8;
+ else if (evdoDbm >= -85) levelEvdoDbm = 4;
+ else if (evdoDbm >= -95) levelEvdoDbm = 2;
+ else if (evdoDbm >= -105) levelEvdoDbm = 1;
+ else levelEvdoDbm = 99;
+
+ if (evdoSnr >= 7) levelEvdoSnr = 16;
+ else if (evdoSnr >= 6) levelEvdoSnr = 8;
+ else if (evdoSnr >= 5) levelEvdoSnr = 4;
+ else if (evdoSnr >= 3) levelEvdoSnr = 2;
+ else if (evdoSnr >= 1) levelEvdoSnr = 1;
+ else levelEvdoSnr = 99;
+
+ int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ if (DBG) log("getEvdoAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get LTE as dBm
+ *
+ * @hide
+ */
+ public int getLteDbm() {
+ log("STOPSHIP teach getLteDbm to compute dBm properly");
+ int level = -1;
+ if (DBG) log("getLteDbm=" + level);
+ return level;
+ }
+
+ /**
+ * Get LTE as level 0..4
+ *
+ * @hide
+ */
+ public int getLteLevel() {
+ log("STOPSHIP teach getLteLevel to compute Level properly");
+ int level = SIGNAL_STRENGTH_MODERATE;
+ if (DBG) log("getLteLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the LTE signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getLteAsuLevel() {
+ log("STOPSHIP teach getLteAsuLevel to compute asu Level properly");
+ int level = 4;
+ if (DBG) log("getLteAsuLevel=" + level);
+ return level;
+ }
+
+ /**
* @return true if this is for GSM
*/
public boolean isGsm() {
@@ -229,10 +598,13 @@
*/
@Override
public int hashCode() {
- return ((mGsmSignalStrength * 0x1234)
- + mGsmBitErrorRate
- + mCdmaDbm + mCdmaEcio
- + mEvdoDbm + mEvdoEcio + mEvdoSnr
+ int primeNum = 31;
+ return ((mGsmSignalStrength * primeNum)
+ + (mGsmBitErrorRate * primeNum)
+ + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
+ + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
+ + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
+ + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
+ (isGsm ? 1 : 0));
}
@@ -260,6 +632,11 @@
&& mEvdoDbm == s.mEvdoDbm
&& mEvdoEcio == s.mEvdoEcio
&& mEvdoSnr == s.mEvdoSnr
+ && mLteSignalStrength == s.mLteSignalStrength
+ && mLteRsrp == s.mLteRsrp
+ && mLteRsrq == s.mLteRsrq
+ && mLteRssnr == s.mLteRssnr
+ && mLteCqi == s.mLteCqi
&& isGsm == s.isGsm);
}
@@ -276,19 +653,12 @@
+ " " + mEvdoDbm
+ " " + mEvdoEcio
+ " " + mEvdoSnr
- + " " + (isGsm ? "gsm" : "cdma"));
- }
-
- /**
- * Test whether two objects hold the same data values or both are null
- *
- * @param a first obj
- * @param b second obj
- * @return true if two objects equal or both are null
- * @hide
- */
- private static boolean equalsHandlesNulls (Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
+ + " " + mLteSignalStrength
+ + " " + mLteRsrp
+ + " " + mLteRsrq
+ + " " + mLteRssnr
+ + " " + mLteCqi
+ + " " + (isGsm ? "gsm|lte" : "cdma"));
}
/**
@@ -305,6 +675,11 @@
mEvdoDbm = m.getInt("EvdoDbm");
mEvdoEcio = m.getInt("EvdoEcio");
mEvdoSnr = m.getInt("EvdoSnr");
+ mLteSignalStrength = m.getInt("LteSignalStrength");
+ mLteRsrp = m.getInt("LteRsrp");
+ mLteRsrq = m.getInt("LteRsrq");
+ mLteRssnr = m.getInt("LteRssnr");
+ mLteCqi = m.getInt("LteCqi");
isGsm = m.getBoolean("isGsm");
}
@@ -322,6 +697,18 @@
m.putInt("EvdoDbm", mEvdoDbm);
m.putInt("EvdoEcio", mEvdoEcio);
m.putInt("EvdoSnr", mEvdoSnr);
+ m.putInt("LteSignalStrength", mLteSignalStrength);
+ m.putInt("LteRsrp", mLteRsrp);
+ m.putInt("LteRsrq", mLteRsrq);
+ m.putInt("LteRssnr", mLteRssnr);
+ m.putInt("LteCqi", mLteCqi);
m.putBoolean("isGsm", Boolean.valueOf(isGsm));
}
+
+ /**
+ * log
+ */
+ private static void log(String s) {
+ Log.w(LOG_TAG, s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 815fbfb..9b19600 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -47,8 +47,8 @@
protected RegistrantList mRUIMLockedRegistrants = new RegistrantList();
protected RegistrantList mNVReadyRegistrants = new RegistrantList();
protected RegistrantList mCallStateRegistrants = new RegistrantList();
- protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mDataConnectionRegistrants = new RegistrantList();
+ protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
+ protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
@@ -65,6 +65,9 @@
protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
+ protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
+ protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
+ protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
@@ -293,24 +296,24 @@
mCallStateRegistrants.remove(h);
}
- public void registerForNetworkStateChanged(Handler h, int what, Object obj) {
+ public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mNetworkStateRegistrants.add(r);
+ mVoiceNetworkStateRegistrants.add(r);
}
- public void unregisterForNetworkStateChanged(Handler h) {
- mNetworkStateRegistrants.remove(h);
+ public void unregisterForVoiceNetworkStateChanged(Handler h) {
+ mVoiceNetworkStateRegistrants.remove(h);
}
- public void registerForDataStateChanged(Handler h, int what, Object obj) {
+ public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mDataConnectionRegistrants.add(r);
+ mDataNetworkStateRegistrants.add(r);
}
- public void unregisterForDataStateChanged(Handler h) {
- mDataConnectionRegistrants.remove(h);
+ public void unregisterForDataNetworkStateChanged(Handler h) {
+ mDataNetworkStateRegistrants.remove(h);
}
public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
@@ -588,6 +591,39 @@
mResendIncallMuteRegistrants.remove(h);
}
+ @Override
+ public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCdmaSubscriptionChangedRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForCdmaSubscriptionChanged(Handler h) {
+ mCdmaSubscriptionChangedRegistrants.remove(h);
+ }
+
+ @Override
+ public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCdmaPrlChangedRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForCdmaPrlChanged(Handler h) {
+ mCdmaPrlChangedRegistrants.remove(h);
+ }
+
+ @Override
+ public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mExitEmergencyCallbackModeRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForExitEmergencyCallbackMode(Handler h) {
+ mExitEmergencyCallbackModeRegistrants.remove(h);
+ }
+
//***** Protected Methods
/**
* Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 259acdb..21e9e44 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -216,10 +216,10 @@
void registerForCallStateChanged(Handler h, int what, Object obj);
void unregisterForCallStateChanged(Handler h);
- void registerForNetworkStateChanged(Handler h, int what, Object obj);
- void unregisterForNetworkStateChanged(Handler h);
- void registerForDataStateChanged(Handler h, int what, Object obj);
- void unregisterForDataStateChanged(Handler h);
+ void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
+ void unregisterForVoiceNetworkStateChanged(Handler h);
+ void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
+ void unregisterForDataNetworkStateChanged(Handler h);
void registerForRadioTechnologyChanged(Handler h, int what, Object obj);
void unregisterForRadioTechnologyChanged(Handler h);
@@ -549,6 +549,39 @@
void registerForResendIncallMute(Handler h, int what, Object obj);
void unregisterForResendIncallMute(Handler h);
+ /**
+ * Registers the handler for when Cdma subscription changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
+ void unregisterForCdmaSubscriptionChanged(Handler h);
+
+ /**
+ * Registers the handler for when Cdma prl changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForCdmaPrlChanged(Handler h, int what, Object obj);
+ void unregisterForCdmaPrlChanged(Handler h);
+
+ /**
+ * Registers the handler for when Cdma prl changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
+ void unregisterForExitEmergencyCallbackMode(Handler h);
+
/**
* Supply the ICC PIN to the ICC card
*
@@ -564,7 +597,23 @@
void supplyIccPin(String pin, Message result);
/**
- * Supply the ICC PUK to the ICC card
+ * Supply the PIN for the app with this AID on the ICC card
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPinForApp(String pin, String aid, Message result);
+
+ /**
+ * Supply the ICC PUK and newPin to the ICC card
*
* returned message
* retMsg.obj = AsyncResult ar
@@ -578,6 +627,22 @@
void supplyIccPuk(String puk, String newPin, Message result);
/**
+ * Supply the PUK, new pin for the app with this AID on the ICC card
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
+
+ /**
* Supply the ICC PIN2 to the ICC card
* Only called following operation where ICC_PIN2 was
* returned as a a failure from a previous operation
@@ -594,6 +659,24 @@
void supplyIccPin2(String pin2, Message result);
/**
+ * Supply the PIN2 for the app with this AID on the ICC card
+ * Only called following operation where ICC_PIN2 was
+ * returned as a a failure from a previous operation
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPin2ForApp(String pin2, String aid, Message result);
+
+ /**
* Supply the SIM PUK2 to the SIM card
* Only called following operation where SIM_PUK2 was
* returned as a a failure from a previous operation
@@ -609,8 +692,28 @@
void supplyIccPuk2(String puk2, String newPin2, Message result);
+ /**
+ * Supply the PUK2, newPin2 for the app with this AID on the ICC card
+ * Only called following operation where SIM_PUK2 was
+ * returned as a a failure from a previous operation
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
+
void changeIccPin(String oldPin, String newPin, Message result);
+ void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
void changeIccPin2(String oldPin2, String newPin2, Message result);
+ void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
@@ -853,7 +956,7 @@
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- void getRegistrationState (Message response);
+ void getVoiceRegistrationState (Message response);
/**
* response.obj.result is an int[3]
@@ -865,7 +968,7 @@
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- void getGPRSRegistrationState (Message response);
+ void getDataRegistrationState (Message response);
/**
* response.obj.result is a String[3]
@@ -1286,7 +1389,7 @@
* @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_*
* @param response is callback message
*/
- void setCdmaSubscription(int cdmaSubscriptionType, Message response);
+ void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
/**
* Set the TTY mode
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index df12153..fda1e47 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -30,6 +30,7 @@
public String ifname = "";
public String [] addresses = new String[0];
public String [] dnses = new String[0];
+ public String[] gateways = new String[0];
@Override
public String toString() {
@@ -53,6 +54,12 @@
sb.append(",");
}
if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
+ sb.append("] gateways=[");
+ for (String addr : gateways) {
+ sb.append(addr);
+ sb.append(",");
+ }
+ if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
sb.append("]}");
return sb.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index aa9c4a3..e0b9603 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -398,22 +398,34 @@
// a failure we'll clear again at the bottom of this code.
LinkProperties linkProperties = new LinkProperties();
if (response.status == FailCause.NONE.getErrorCode()) {
+ String propertyPrefix = "net." + response.ifname + ".";
+
try {
cid = response.cid;
linkProperties.setInterfaceName(response.ifname);
if (response.addresses != null && response.addresses.length > 0) {
for (String addr : response.addresses) {
LinkAddress la;
+ int addrPrefixLen;
+
+ String [] ap = addr.split("/");
+ if (ap.length == 2) {
+ addr = ap[0];
+ addrPrefixLen = Integer.parseInt(ap[1]);
+ } else {
+ addrPrefixLen = 0;
+ }
if (!InetAddress.isNumeric(addr)) {
EventLogTags.writeBadIpAddress(addr);
throw new UnknownHostException("Non-numeric ip addr=" + addr);
}
InetAddress ia = InetAddress.getByName(addr);
- if (ia instanceof Inet4Address) {
- la = new LinkAddress(ia, 32);
- } else {
- la = new LinkAddress(ia, 128);
+ if (addrPrefixLen == 0) {
+ // Assume point to point
+ addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
}
+ if (DBG) log("addr/pl=" + addr + "/" + addrPrefixLen);
+ la = new LinkAddress(ia, addrPrefixLen);
linkProperties.addLinkAddress(la);
}
} else {
@@ -431,11 +443,9 @@
}
result = SetupResult.SUCCESS;
} else {
- String prefix = "net." + response.ifname + ".";
-
String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(prefix + "dns1");
- dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
+ dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
if (isDnsOk(dnsServers)) {
for (String dnsAddr : dnsServers) {
if (!InetAddress.isNumeric(dnsAddr)) {
@@ -457,6 +467,23 @@
throw new UnknownHostException("Unacceptable dns addresses=" + sb);
}
}
+ if ((response.gateways == null) || (response.gateways.length == 0)) {
+ String gateways = SystemProperties.get(propertyPrefix + "gw");
+ if (gateways != null) {
+ response.gateways = gateways.split(" ");
+ } else {
+ response.gateways = new String[0];
+ }
+ }
+ for (String addr : response.gateways) {
+ if (!InetAddress.isNumeric(addr)) {
+ EventLogTags.writePdpBadDnsAddress("gateway=" + addr);
+ throw new UnknownHostException("Non-numeric gateway addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ linkProperties.addGateway(ia);
+ }
+ result = SetupResult.SUCCESS;
} catch (UnknownHostException e) {
log("onSetupCompleted: UnknownHostException " + e);
e.printStackTrace();
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
index 0e7bad7..7199616 100644
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java
@@ -34,7 +34,7 @@
boolean isCardPresent() {
return this == CARDSTATE_PRESENT;
}
- };
+ }
public enum PinState {
PINSTATE_UNKNOWN,
@@ -43,12 +43,13 @@
PINSTATE_DISABLED,
PINSTATE_ENABLED_BLOCKED,
PINSTATE_ENABLED_PERM_BLOCKED
- };
+ }
private CardState mCardState;
private PinState mUniversalPinState;
private int mGsmUmtsSubscriptionAppIndex;
private int mCdmaSubscriptionAppIndex;
+ private int mImsSubscriptionAppIndex;
private int mNumApplications;
private ArrayList<IccCardApplication> mApplications =
@@ -74,6 +75,10 @@
}
}
+ public PinState getUniversalPinState() {
+ return mUniversalPinState;
+ }
+
public void setUniversalPinState(int state) {
switch(state) {
case 0:
@@ -115,6 +120,14 @@
mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex;
}
+ public int getImsSubscriptionAppIndex() {
+ return mImsSubscriptionAppIndex;
+ }
+
+ public void setImsSubscriptionAppIndex(int imsSubscriptionAppIndex) {
+ mImsSubscriptionAppIndex = imsSubscriptionAppIndex;
+ }
+
public int getNumApplications() {
return mNumApplications;
}
@@ -130,4 +143,5 @@
public IccCardApplication getApplication(int index) {
return mApplications.get(index);
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index cbff130..54341b1 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -679,7 +679,7 @@
* Set the status of the CDMA subscription mode
*/
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
- mCM.setCdmaSubscription(cdmaSubscriptionType, response);
+ mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index b31161c..898e624 100644
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -95,25 +95,17 @@
}
/**
- * Returns current signal strength in "asu", ranging from 0-31
- * or -1 if unknown
+ * Returns current signal strength in as an asu 0..31
*
- * For GSM, dBm = -113 + 2*asu
- * 0 means "-113 dBm or less"
- * 31 means "-51 dBm or greater"
- *
- * @return signal strength in asu, -1 if not yet updated
* Throws RuntimeException if client has not called notifySignalStrength()
*/
- public int getSignalStrength() {
+ public int getSignalStrengthLevelAsu() {
// TODO: use new SignalStrength instead of asu
if ((mWants & NOTIF_SIGNAL) == 0) {
throw new RuntimeException
("client must call notifySignalStrength(int)");
}
- int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
-
- return (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
+ return mSignalStrength.getAsuLevel();
}
/**
@@ -128,19 +120,7 @@
throw new RuntimeException
("client must call notifySignalStrength(int)");
}
-
- int dBm = -1;
-
- if(!mSignalStrength.isGsm()) {
- dBm = mSignalStrength.getCdmaDbm();
- } else {
- int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
- int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
- if (asu != -1) {
- dBm = -113 + 2*asu;
- }
- }
- return dBm;
+ return mSignalStrength.getDbm();
}
public void notifyPhoneCallState(int eventWhat) {
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 3ef1924..76c6229 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -224,7 +224,6 @@
RILSender mSender;
Thread mReceiverThread;
RILReceiver mReceiver;
- private Context mContext;
WakeLock mWakeLock;
int mWakeLockTimeout;
// The number of requests pending to be sent out, it increases before calling
@@ -649,8 +648,6 @@
mRequestMessagesPending = 0;
mRequestMessagesWaiting = 0;
- mContext = context;
-
mSenderThread = new HandlerThread("RILSender");
mSenderThread.start();
@@ -693,90 +690,126 @@
send(rr);
}
- public void
+ @Override public void
supplyIccPin(String pin, Message result) {
+ supplyIccPinForApp(pin, null, result);
+ }
+
+ @Override public void
+ supplyIccPinForApp(String pin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(1);
+ rr.mp.writeInt(2);
rr.mp.writeString(pin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
supplyIccPuk(String puk, String newPin, Message result) {
+ supplyIccPukForApp(puk, newPin, null, result);
+ }
+
+ @Override public void
+ supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(puk);
rr.mp.writeString(newPin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
supplyIccPin2(String pin, Message result) {
+ supplyIccPin2ForApp(pin, null, result);
+ }
+
+ @Override public void
+ supplyIccPin2ForApp(String pin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(1);
+ rr.mp.writeInt(2);
rr.mp.writeString(pin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
- supplyIccPuk2(String puk, String newPin2, Message result) {
+ @Override public void
+ supplyIccPuk2(String puk2, String newPin2, Message result) {
+ supplyIccPuk2ForApp(puk2, newPin2, null, result);
+ }
+
+ @Override public void
+ supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(puk);
rr.mp.writeString(newPin2);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
changeIccPin(String oldPin, String newPin, Message result) {
+ changeIccPinForApp(oldPin, newPin, null, result);
+ }
+
+ @Override public void
+ changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(oldPin);
rr.mp.writeString(newPin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
changeIccPin2(String oldPin2, String newPin2, Message result) {
+ changeIccPin2ForApp(oldPin2, newPin2, null, result);
+ }
+
+ @Override public void
+ changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(oldPin2);
rr.mp.writeString(newPin2);
+ rr.mp.writeString(aid);
send(rr);
}
@@ -1072,9 +1105,9 @@
}
public void
- getRegistrationState (Message result) {
+ getVoiceRegistrationState (Message result) {
RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_REGISTRATION_STATE, result);
+ = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1082,9 +1115,9 @@
}
public void
- getGPRSRegistrationState (Message result) {
+ getDataRegistrationState (Message result) {
RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_GPRS_REGISTRATION_STATE, result);
+ = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1357,7 +1390,7 @@
send(rrPnt);
RILRequest rrCs = RILRequest.obtain(
- RIL_REQUEST_CDMA_SET_SUBSCRIPTION, null);
+ RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, null);
rrCs.mp.writeInt(1);
rrCs.mp.writeInt(mCdmaSubscription);
if (RILJ_LOGD) riljLog(rrCs.serialString() + "> "
@@ -2171,8 +2204,8 @@
case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
- case RIL_REQUEST_REGISTRATION_STATE: ret = responseStrings(p); break;
- case RIL_REQUEST_GPRS_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
@@ -2228,7 +2261,7 @@
case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
@@ -2255,6 +2288,7 @@
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
@@ -2368,7 +2402,7 @@
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
@@ -2396,6 +2430,9 @@
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized unsol response: " + response);
@@ -2420,10 +2457,10 @@
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
- mNetworkStateRegistrants
+ mVoiceNetworkStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
case RIL_UNSOL_RESPONSE_NEW_SMS: {
@@ -2515,7 +2552,7 @@
case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
if (RILJ_LOGD) unsljLogRet(response, ret);
- mDataConnectionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
+ mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
@@ -2698,6 +2735,34 @@
mResendIncallMuteRegistrants.notifyRegistrants(
new AsyncResult (null, ret, null));
}
+ break;
+
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaSubscriptionChangedRegistrants != null) {
+ mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOl_CDMA_PRL_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaPrlChangedRegistrants != null) {
+ mCdmaPrlChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mExitEmergencyCallbackModeRegistrants != null) {
+ mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
+ new AsyncResult (null, null, null));
+ }
+ break;
}
}
@@ -2848,6 +2913,7 @@
status.setUniversalPinState(p.readInt());
status.setGsmUmtsSubscriptionAppIndex(p.readInt());
status.setCdmaSubscriptionAppIndex(p.readInt());
+ status.setImsSubscriptionAppIndex(p.readInt());
int numApplications = p.readInt();
// limit to maximum allowed applications
@@ -2905,16 +2971,15 @@
dc.uusInfo.setDcs(p.readInt());
byte[] userData = p.createByteArray();
dc.uusInfo.setUserData(userData);
- Log
- .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+ riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
dc.uusInfo.getType(), dc.uusInfo.getDcs(),
dc.uusInfo.getUserData().length));
- Log.v(LOG_TAG, "Incoming UUS : data (string)="
+ riljLogv("Incoming UUS : data (string)="
+ new String(dc.uusInfo.getUserData()));
- Log.v(LOG_TAG, "Incoming UUS : data (hex): "
+ riljLogv("Incoming UUS : data (hex): "
+ IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
} else {
- Log.v(LOG_TAG, "Incoming UUS : NOT present!");
+ riljLogv("Incoming UUS : NOT present!");
}
// Make sure there's a leading + on addresses with a TOA of 145
@@ -2924,10 +2989,10 @@
if (dc.isVoicePrivacy) {
mVoicePrivacyOnRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
+ riljLog("InCall VoicePrivacy is enabled");
} else {
mVoicePrivacyOffRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
+ riljLog("InCall VoicePrivacy is disabled");
}
}
@@ -2944,7 +3009,6 @@
dataCall.cid = p.readInt();
dataCall.active = p.readInt();
dataCall.type = p.readString();
- p.readString(); // Ignore apn
String addresses = p.readString();
if (TextUtils.isEmpty(addresses)) {
dataCall.addresses = addresses.split(" ");
@@ -2966,6 +3030,10 @@
if (!TextUtils.isEmpty(dnses)) {
dataCall.dnses = dnses.split(" ");
}
+ String gateways = p.readString();
+ if (!TextUtils.isEmpty(gateways)) {
+ dataCall.gateways = gateways.split(" ");
+ }
}
return dataCall;
}
@@ -2976,7 +3044,7 @@
int ver = p.readInt();
int num = p.readInt();
- Log.d(LOG_TAG, "responseDataCallList ver=" + ver + " num=" + num);
+ riljLog("responseDataCallList ver=" + ver + " num=" + num);
response = new ArrayList<DataCallState>(num);
for (int i = 0; i < num; i++) {
@@ -2990,7 +3058,7 @@
responseSetupDataCall(Parcel p) {
int ver = p.readInt();
int num = p.readInt();
- Log.d(LOG_TAG, "responseSetupDataCall ver=" + ver + " num=" + num);
+ if (RILJ_LOGD) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
DataCallState dataCall;
@@ -3009,11 +3077,18 @@
}
if (num >= 4) {
String dnses = p.readString();
- Log.d(LOG_TAG, "responseSetupDataCall got dnses=" + dnses);
+ if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
if (!TextUtils.isEmpty(dnses)) {
dataCall.dnses = dnses.split(" ");
}
}
+ if (num >= 5) {
+ String gateways = p.readString();
+ if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
+ if (!TextUtils.isEmpty(gateways)) {
+ dataCall.gateways = gateways.split(" ");
+ }
+ }
} else {
if (num != 1) {
throw new RuntimeException(
@@ -3156,7 +3231,7 @@
private Object
responseSignalStrength(Parcel p) {
- int numInts = 7;
+ int numInts = 12;
int response[];
/* TODO: Add SignalStrength class to match RIL_SignalStrength */
@@ -3200,6 +3275,8 @@
notification.signalType = p.readInt();
notification.alertPitch = p.readInt();
notification.signal = p.readInt();
+ notification.numberType = p.readInt();
+ notification.numberPlan = p.readInt();
return notification;
}
@@ -3291,8 +3368,8 @@
case RIL_REQUEST_UDUB: return "UDUB";
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
- case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
- case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
+ case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
case RIL_REQUEST_OPERATOR: return "OPERATOR";
case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
case RIL_REQUEST_DTMF: return "DTMF";
@@ -3348,7 +3425,7 @@
case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION";
+ case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
@@ -3375,6 +3452,7 @@
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
+ case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
default: return "<unknown request>";
}
}
@@ -3390,7 +3468,7 @@
switch(request) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
@@ -3419,6 +3497,9 @@
case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED: return "CDMA_SUBSCRIPTION_CHANGED";
+ case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
default: return "<unknown reponse>";
}
}
@@ -3502,9 +3583,9 @@
/**
* {@inheritDoc}
*/
- public void setCdmaSubscription(int cdmaSubscription , Message response) {
+ public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION, response);
+ RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
rr.mp.writeInt(1);
rr.mp.writeInt(cdmaSubscription);
@@ -3518,6 +3599,19 @@
/**
* {@inheritDoc}
*/
+ public void getCdmaSubscriptionSource(int cdmaSubscription , Message response) {
+ RILRequest rr = RILRequest.obtain(
+ RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + cdmaSubscription);
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void queryTTYMode(Message response) {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
@@ -3598,4 +3692,5 @@
send(rr);
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 9b21de8..cdf1977 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -162,8 +162,8 @@
int RIL_REQUEST_UDUB = 17;
int RIL_REQUEST_LAST_CALL_FAIL_CAUSE = 18;
int RIL_REQUEST_SIGNAL_STRENGTH = 19;
- int RIL_REQUEST_REGISTRATION_STATE = 20;
- int RIL_REQUEST_GPRS_REGISTRATION_STATE = 21;
+ int RIL_REQUEST_VOICE_REGISTRATION_STATE = 20;
+ int RIL_REQUEST_DATA_REGISTRATION_STATE = 21;
int RIL_REQUEST_OPERATOR = 22;
int RIL_REQUEST_RADIO_POWER = 23;
int RIL_REQUEST_DTMF = 24;
@@ -219,7 +219,7 @@
int RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE = 74;
int RIL_REQUEST_GET_NEIGHBORING_CELL_IDS = 75;
int RIL_REQUEST_SET_LOCATION_UPDATES = 76;
- int RIL_REQUEST_CDMA_SET_SUBSCRIPTION = 77;
+ int RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77;
int RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78;
int RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79;
int RIL_REQUEST_SET_TTY_MODE = 80;
@@ -246,10 +246,11 @@
int RIL_REQUEST_SET_SMSC_ADDRESS = 101;
int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
+ int RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
- int RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED = 1002;
+ int RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
int RIL_UNSOL_RESPONSE_NEW_SMS = 1003;
int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005;
@@ -278,4 +279,7 @@
int RIL_UNSOL_OEM_HOOK_RAW = 1028;
int RIL_UNSOL_RINGBACK_TONE = 1029;
int RIL_UNSOL_RESEND_INCALL_MUTE = 1030;
+ int RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED = 1031;
+ int RIL_UNSOl_CDMA_PRL_CHANGED = 1032;
+ int RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
index f4119ad..81ff042 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -26,10 +26,12 @@
*/
public class CdmaCallWaitingNotification {
static final String LOG_TAG = "CDMA";
- public String number =null;
+ public String number = null;
public int numberPresentation = 0;
public String name = null;
public int namePresentation = 0;
+ public int numberType = 0;
+ public int numberPlan = 0;
public int isPresent = 0;
public int signalType = 0;
public int alertPitch = 0;
@@ -42,6 +44,8 @@
+ " numberPresentation: " + numberPresentation
+ " name: " + name
+ " namePresentation: " + namePresentation
+ + " numberType: " + numberType
+ + " numberPlan: " + numberPlan
+ " isPresent: " + isPresent
+ " signalType: " + signalType
+ " alertPitch: " + alertPitch
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index c324a71..8c36106 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -101,7 +101,7 @@
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mRuimRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
p.mCM.registerForNVReady(this, EVENT_NV_READY, null);
- p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
p.mSST.registerForCdmaDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
@@ -125,7 +125,7 @@
mPhone.mCM.unregisterForOffOrNotAvailable(this);
mCdmaPhone.mRuimRecords.unregisterForRecordsLoaded(this);
mPhone.mCM.unregisterForNVReady(this);
- mPhone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionAttached(this);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b217f07..0debb42 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -186,7 +186,7 @@
cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
- cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
+ cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
@@ -215,7 +215,7 @@
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
- cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForVoiceNetworkStateChanged(this);
cm.unregisterForRUIMReady(this);
cm.unregisterForNVReady(this);
cm.unregisterForCdmaOtaProvision(this);
@@ -517,7 +517,7 @@
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
+ cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
}
break;
@@ -897,7 +897,8 @@
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, false);
}
/**
@@ -955,8 +956,8 @@
obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
pollingContext[0]++;
- // RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA
- cm.getRegistrationState(
+ // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
+ cm.getVoiceRegistrationState(
obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
break;
@@ -1252,7 +1253,7 @@
//log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
// cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
- evdoRssi, evdoEcio, evdoSnr, false);
+ evdoRssi, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, false);
}
try {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index f2cdf0c..c57f2f1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -141,7 +141,7 @@
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
@@ -171,7 +171,7 @@
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
- mPhone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
mGsmPhone.mSST.unregisterForGprsAttached(this);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index bb99e45..ac83808 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -79,6 +79,10 @@
private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
+ private int mMaxDataCalls = 1;
+ private int mNewMaxDataCalls = 1;
+ private int mReasonDataDenied = -1;
+ private int mNewReasonDataDenied = -1;
/**
* Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
@@ -212,7 +216,7 @@
cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
- cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
+ cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
@@ -248,7 +252,7 @@
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
- cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForVoiceNetworkStateChanged(this);
cm.unregisterForSIMReady(this);
phone.mSIMRecords.unregisterForRecordsLoaded(this);
@@ -491,7 +495,7 @@
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
+ cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
}
break;
@@ -683,6 +687,7 @@
int lac = -1;
int cid = -1;
int regState = -1;
+ int reasonRegStateDenied = -1;
int psc = -1;
if (states.length > 0) {
try {
@@ -724,6 +729,8 @@
int type = 0;
regState = -1;
+ mNewReasonDataDenied = -1;
+ mNewMaxDataCalls = 1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
@@ -732,6 +739,12 @@
if (states.length >= 4 && states[3] != null) {
type = Integer.parseInt(states[3]);
}
+ if ((states.length >= 5 ) && (regState == 3)) {
+ mNewReasonDataDenied = Integer.parseInt(states[4]);
+ }
+ if (states.length >= 6) {
+ mNewMaxDataCalls = Integer.parseInt(states[5]);
+ }
} catch (NumberFormatException ex) {
Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
}
@@ -785,7 +798,7 @@
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, true);
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, true);
}
/**
@@ -842,12 +855,12 @@
EVENT_POLL_STATE_OPERATOR, pollingContext));
pollingContext[0]++;
- cm.getGPRSRegistrationState(
+ cm.getDataRegistrationState(
obtainMessage(
EVENT_POLL_STATE_GPRS, pollingContext));
pollingContext[0]++;
- cm.getRegistrationState(
+ cm.getVoiceRegistrationState(
obtainMessage(
EVENT_POLL_STATE_REGISTRATION, pollingContext));
@@ -894,7 +907,11 @@
if (DBG) {
Log.d(LOG_TAG, "Poll ServiceState done: " +
" oldSS=[" + ss + "] newSS=[" + newSS +
- "] oldGprs=" + gprsState + " newGprs=" + newGPRSState +
+ "] oldGprs=" + gprsState + " newData=" + newGPRSState +
+ " oldMaxDataCalls=" + mMaxDataCalls +
+ " mNewMaxDataCalls=" + mNewMaxDataCalls +
+ " oldReasonDataDenied=" + mReasonDataDenied +
+ " mNewReasonDataDenied=" + mNewReasonDataDenied +
" oldType=" + networkTypeToString(networkType) +
" newType=" + networkTypeToString(newNetworkType));
}
@@ -956,6 +973,8 @@
}
gprsState = newGPRSState;
+ mReasonDataDenied = mNewReasonDataDenied;
+ mMaxDataCalls = mNewMaxDataCalls;
networkType = newNetworkType;
// this new state has been applied - forget it until we get a new new state
newNetworkType = 0;
@@ -1158,6 +1177,11 @@
private void onSignalStrengthResult(AsyncResult ar) {
SignalStrength oldSignalStrength = mSignalStrength;
int rssi = 99;
+ int lteSignalStrength = -1;
+ int lteRsrp = -1;
+ int lteRsrq = -1;
+ int lteRssnr = -1;
+ int lteCqi = -1;
if (ar.exception != null) {
// -1 = unknown
@@ -1169,6 +1193,11 @@
// bug 658816 seems to be a case where the result is 0-length
if (ints.length != 0) {
rssi = ints[0];
+ lteSignalStrength = ints[7];
+ lteRsrp = ints[8];
+ lteRsrq = ints[9];
+ lteRssnr = ints[10];
+ lteCqi = ints[11];
} else {
Log.e(LOG_TAG, "Bogus signal strength response");
rssi = 99;
@@ -1176,7 +1205,7 @@
}
mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
- -1, -1, -1, true);
+ -1, -1, -1, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
if (!mSignalStrength.equals(oldSignalStrength)) {
try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
index 41f3b23..a9efc98 100755
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -305,8 +305,15 @@
fileIds = mPbrFile.mFileIds.get(recNum);
if (fileIds == null || fileIds.isEmpty()) return;
+
+ int extEf = 0;
+ // Only call fileIds.get while EFEXT1_TAG is available
+ if (fileIds.containsKey(USIM_EFEXT1_TAG)) {
+ extEf = fileIds.get(USIM_EFEXT1_TAG);
+ }
+
mAdnCache.requestLoadAllAdnLike(fileIds.get(USIM_EFADN_TAG),
- fileIds.get(USIM_EFEXT1_TAG), obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
+ extEf, obtainMessage(EVENT_USIM_ADN_LOAD_DONE));
try {
mLock.wait();
} catch (InterruptedException e) {
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 1939f95..b6c3b67 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -144,10 +144,10 @@
public void getSignalStrength (Message result) {
}
- public void getRegistrationState (Message result) {
+ public void getVoiceRegistrationState (Message result) {
}
- public void getGPRSRegistrationState (Message result) {
+ public void getDataRegistrationState (Message result) {
}
public void getOperator(Message result) {
@@ -339,7 +339,7 @@
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
}
- public void setCdmaSubscription(int cdmaSubscription , Message response) {
+ public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
}
public void queryTTYMode(Message response) {
@@ -362,4 +362,29 @@
public void exitEmergencyCallbackMode(Message response) {
}
+
+ @Override
+ public void supplyIccPinForApp(String pin, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
+ }
+
+ @Override
+ public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
+ }
+
+ @Override
+ public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
+ Message response) {
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 8b3a3ad..242d44f 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -825,7 +825,7 @@
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- public void getRegistrationState (Message result) {
+ public void getVoiceRegistrationState (Message result) {
String ret[] = new String[14];
ret[0] = "5"; // registered roam
@@ -863,7 +863,7 @@
* Please note that registration state 4 ("unknown") is treated
* as "out of service" in the Android telephony system
*/
- public void getGPRSRegistrationState (Message result) {
+ public void getDataRegistrationState (Message result) {
String ret[] = new String[4];
ret[0] = "5"; // registered roam
@@ -1361,7 +1361,7 @@
}
public void
- setCdmaSubscription(int cdmaSubscriptionType, Message response) {
+ setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
}
@@ -1468,4 +1468,35 @@
public void getGsmBroadcastConfig(Message response) {
unimplemented(response);
}
+
+ @Override
+ public void supplyIccPinForApp(String pin, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
+ Message response) {
+ unimplemented(response);
+ }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 90dcc27..acc7379 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -192,6 +192,7 @@
Capability.UNBOUND_RENDERING,
Capability.CUSTOM_BACKGROUND_COLOR,
Capability.RENDER,
+ Capability.LAYOUT_ONLY,
Capability.EMBEDDED_LAYOUT,
Capability.VIEW_MANIPULATION,
Capability.PLAY_ANIMATION,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 33dd214..7d794bd 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -425,36 +425,72 @@
}
}
- if (defStyleValues == null && defStyleAttr != 0) {
- // get the name from the int.
- String defStyleName = searchAttr(defStyleAttr);
+ if (defStyleValues == null) {
+ if (defStyleAttr != 0) {
+ // get the name from the int.
+ String defStyleName = searchAttr(defStyleAttr);
- if (defaultPropMap != null) {
- defaultPropMap.put("style", defStyleName);
- }
-
- // look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
-
- if (item != null) {
- // item is a reference to a style entry. Search for it.
- item = mRenderResources.findResValue(item.getValue(),
- false /*forceFrameworkOnly*/);
-
- if (item instanceof StyleResourceValue) {
- defStyleValues = (StyleResourceValue)item;
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", defStyleName);
}
- } else {
- Bridge.getLog().error(null,
- String.format(
- "Failed to find style '%s' in current theme", defStyleName),
- null /*data*/);
- }
- }
- if (defStyleRes != 0) {
- // FIXME: See what we need to do with this.
- throw new UnsupportedOperationException();
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
+
+ if (item != null) {
+ // item is a reference to a style entry. Search for it.
+ item = mRenderResources.findResValue(item.getValue(),
+ false /*forceFrameworkOnly*/);
+
+ if (item instanceof StyleResourceValue) {
+ defStyleValues = (StyleResourceValue)item;
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style '%s' in current theme", defStyleName),
+ null /*data*/);
+ }
+ } else if (defStyleRes != 0) {
+ Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
+ if (value == null) {
+ value = mProjectCallback.resolveResourceId(defStyleRes);
+ }
+
+ if (value != null) {
+ if (value.getFirst() == ResourceType.STYLE) {
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
+ if (item != null) {
+ if (item instanceof StyleResourceValue) {
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", item.getName());
+ }
+
+ defStyleValues = (StyleResourceValue)item;
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Style with id 0x%x (resolved to '%s') does not exist.",
+ defStyleRes, value.getSecond()),
+ null /*data*/);
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Resouce id 0x%x is not of type STYLE (instead %s)",
+ defStyleRes, value.getFirst().toString()),
+ null /*data*/);
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style with id 0x%x in current theme",
+ defStyleRes),
+ null /*data*/);
+ }
+ }
}
String namespace = BridgeConstants.NS_RESOURCES;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 30da2ff..c1d7600 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -188,6 +188,10 @@
String s = mResourceData[index].getValue();
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
try {
return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue);
} catch (NumberFormatException e) {
@@ -301,6 +305,10 @@
return null;
}
+ if (RenderResources.REFERENCE_NULL.equals(value)) {
+ return null;
+ }
+
// let the framework inflate the ColorStateList from the XML file.
File f = new File(value);
if (f.isFile()) {
@@ -337,8 +345,6 @@
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null /*data*/);
}
- assert false;
-
return null;
}
@@ -408,6 +414,10 @@
return LayoutParams.WRAP_CONTENT;
}
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
if (ResourceHelper.stringToFloat(s, mValue)) {
return mValue.getDimension(mBridgeResources.mMetrics);
}
@@ -418,8 +428,6 @@
"\"%1$s\" in attribute \"%2$s\" is not a valid format.",
s, mNames[index]), null /*data*/);
- assert false;
-
return defValue;
}
@@ -480,6 +488,10 @@
return LayoutParams.WRAP_CONTENT;
}
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
// FIXME huh?
float f = getDimension(index, defValue);
@@ -553,8 +565,6 @@
"\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.",
value, mNames[index]), null /*data*/);
- assert false;
-
return defValue;
}
@@ -588,6 +598,10 @@
return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
}
+ if (RenderResources.REFERENCE_NULL.equals(resValue.getValue())) {
+ return defValue;
+ }
+
// if the attribute was a reference to a resource, and not a declaration of an id (@+id),
// then the xml attribute value was "resolved" which leads us to a ResourceValue with a
// valid getType() and getName() returning a resource name.
@@ -666,8 +680,6 @@
"Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
resValue);
- assert false;
-
return defValue;
}
@@ -715,6 +727,10 @@
String value = mResourceData[index].getValue();
if (value != null) {
+ if (RenderResources.REFERENCE_NULL.equals(value)) {
+ return null;
+ }
+
return new CharSequence[] { value };
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index fedd789f..2fd58e4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -421,57 +421,63 @@
// now do the layout.
mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
- mViewRoot.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+ if (params.isLayoutOnly()) {
+ // delete the canvas and image to reset them on the next full rendering
+ mImage = null;
+ mCanvas = null;
+ } else {
+ mViewRoot.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
- // draw the views
- // create the BufferedImage into which the layout will be rendered.
- boolean newImage = false;
- if (newRenderSize || mCanvas == null) {
- if (params.getImageFactory() != null) {
- mImage = params.getImageFactory().getImage(
- mMeasuredScreenWidth,
- mMeasuredScreenHeight);
- } else {
- mImage = new BufferedImage(
- mMeasuredScreenWidth,
- mMeasuredScreenHeight,
- BufferedImage.TYPE_INT_ARGB);
- newImage = true;
+ // draw the views
+ // create the BufferedImage into which the layout will be rendered.
+ boolean newImage = false;
+ if (newRenderSize || mCanvas == null) {
+ if (params.getImageFactory() != null) {
+ mImage = params.getImageFactory().getImage(
+ mMeasuredScreenWidth,
+ mMeasuredScreenHeight);
+ } else {
+ mImage = new BufferedImage(
+ mMeasuredScreenWidth,
+ mMeasuredScreenHeight,
+ BufferedImage.TYPE_INT_ARGB);
+ newImage = true;
+ }
+
+ if (params.isBgColorOverridden()) {
+ // since we override the content, it's the same as if it was a new image.
+ newImage = true;
+ Graphics2D gc = mImage.createGraphics();
+ gc.setColor(new Color(params.getOverrideBgColor(), true));
+ gc.setComposite(AlphaComposite.Src);
+ gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+ gc.dispose();
+ }
+
+ // create an Android bitmap around the BufferedImage
+ Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+ true /*isMutable*/, params.getDensity());
+
+ // create a Canvas around the Android bitmap
+ mCanvas = new Canvas(bitmap);
+ mCanvas.setDensity(params.getDensity().getDpiValue());
}
- if (params.isBgColorOverridden()) {
- // since we override the content, it's the same as if it was a new image.
- newImage = true;
+ if (freshRender && newImage == false) {
Graphics2D gc = mImage.createGraphics();
- gc.setColor(new Color(params.getOverrideBgColor(), true));
gc.setComposite(AlphaComposite.Src);
- gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+
+ gc.setColor(new Color(0x00000000, true));
+ gc.fillRect(0, 0,
+ mMeasuredScreenWidth, mMeasuredScreenHeight);
+
+ // done
gc.dispose();
}
- // create an Android bitmap around the BufferedImage
- Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
- true /*isMutable*/, params.getDensity());
-
- // create a Canvas around the Android bitmap
- mCanvas = new Canvas(bitmap);
- mCanvas.setDensity(params.getDensity().getDpiValue());
+ mViewRoot.draw(mCanvas);
}
- if (freshRender && newImage == false) {
- Graphics2D gc = mImage.createGraphics();
- gc.setComposite(AlphaComposite.Src);
-
- gc.setColor(new Color(0x00000000, true));
- gc.fillRect(0, 0,
- mMeasuredScreenWidth, mMeasuredScreenHeight);
-
- // done
- gc.dispose();
- }
-
- mViewRoot.draw(mCanvas);
-
mViewInfoList = startVisitingViews(mViewRoot, 0);
// success!
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 097b109..8ab9b6a 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -17,6 +17,7 @@
#include <ui/KeyCharacterMap.h>
#include <ui/KeyLayoutMap.h>
#include <ui/VirtualKeyMap.h>
+#include <utils/PropertyMap.h>
#include <utils/String8.h>
#include <stdio.h>
@@ -32,6 +33,7 @@
FILETYPE_KEYLAYOUT,
FILETYPE_KEYCHARACTERMAP,
FILETYPE_VIRTUALKEYDEFINITION,
+ FILETYPE_INPUTDEVICECONFIGURATION,
};
@@ -39,9 +41,9 @@
fprintf(stderr, "Keymap Validation Tool\n\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr,
- " %s [*.kl] [*.kcm] [virtualkeys.*] [...]\n"
- " Validates the specified key layouts, key character maps \n"
- " or virtual key definitions.\n\n",
+ " %s [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
+ " Validates the specified key layouts, key character maps, \n"
+ " input device configurations, or virtual key definitions.\n\n",
gProgName);
}
@@ -54,6 +56,9 @@
if (strcmp(extension, ".kcm") == 0) {
return FILETYPE_KEYCHARACTERMAP;
}
+ if (strcmp(extension, ".idc") == 0) {
+ return FILETYPE_INPUTDEVICECONFIGURATION;
+ }
}
if (strstr(filename, "virtualkeys.")) {
@@ -92,6 +97,16 @@
break;
}
+ case FILETYPE_INPUTDEVICECONFIGURATION: {
+ PropertyMap* map;
+ status_t status = PropertyMap::load(String8(filename), &map);
+ if (status) {
+ fprintf(stderr, "Error %d parsing input device configuration file.\n\n", status);
+ return false;
+ }
+ break;
+ }
+
case FILETYPE_VIRTUALKEYDEFINITION: {
VirtualKeyMap* map;
status_t status = VirtualKeyMap::load(String8(filename), &map);
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
index c7e18df..34d91dd 100644
--- a/voip/java/android/net/sip/SipProfile.java
+++ b/voip/java/android/net/sip/SipProfile.java
@@ -150,9 +150,8 @@
/**
* Sets the username used for authentication.
*
- * @param name auth. name of the profile
+ * @param name authentication username of the profile
* @return this builder object
- * @hide // TODO: remove when we make it public
*/
public Builder setAuthUserName(String name) {
mProfile.mAuthUserName = name;
@@ -391,10 +390,10 @@
/**
* Gets the username for authentication. If it is null, then the username
- * should be used in authentication instead.
+ * is used in authentication instead.
*
- * @return the auth. username
- * @hide // TODO: remove when we make it public
+ * @return the authentication username
+ * @see #getUserName
*/
public String getAuthUserName() {
return mAuthUserName;
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
index 518543a..ac580e7 100644
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ b/voip/java/com/android/server/sip/SipHelper.java
@@ -284,6 +284,13 @@
mHeaderFactory.createContentTypeHeader(
"application", "sdp"));
+ // Adding rport argument in the request could fix some SIP servers
+ // in resolving the initiator's NAT port mapping for relaying the
+ // response message from the other end.
+
+ ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
+ if (viaHeader != null) viaHeader.setRPort();
+
ClientTransaction clientTransaction =
mSipProvider.getNewClientTransaction(request);
if (DEBUG) Log.d(TAG, "send RE-INVITE: " + request);
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 847577f..7a9276d 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -1,16 +1,16 @@
/**
* Copyright (c) 2008, The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -23,6 +23,7 @@
import android.net.wifi.ScanResult;
import android.net.DhcpInfo;
+import android.os.Messenger;
import android.os.WorkSource;
/**
@@ -111,5 +112,7 @@
void forgetNetwork(int networkId);
WpsResult startWps(in WpsConfiguration config);
+
+ Messenger getMessenger();
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index d5fb63e..28a5bc6 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -107,9 +107,16 @@
* generated WEP keys. */
public static final int IEEE8021X = 3;
+ /** WPA2 pre-shared key for use with soft access point
+ * (requires {@code preSharedKey} to be specified).
+ * @hide
+ */
+ public static final int WPA2_PSK = 4;
+
public static final String varName = "key_mgmt";
- public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X" };
+ public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X",
+ "WPA2_PSK" };
}
/**
@@ -480,6 +487,20 @@
dest.writeInt(nextSetBit);
}
+ /** @hide */
+ public int getAuthType() {
+ if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
+ return KeyMgmt.WPA_PSK;
+ } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
+ return KeyMgmt.WPA2_PSK;
+ } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
+ return KeyMgmt.WPA_EAP;
+ } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+ return KeyMgmt.IEEE8021X;
+ }
+ return KeyMgmt.NONE;
+ }
+
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 4312bfd..f60ae48 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -19,7 +19,11 @@
import android.os.Parcelable;
import android.os.Parcel;
import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkUtils;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
import java.util.EnumMap;
/**
@@ -61,7 +65,7 @@
public static final String LINK_SPEED_UNITS = "Mbps";
private int mLinkSpeed;
- private int mIpAddress;
+ private InetAddress mIpAddress;
private String mMacAddress;
@@ -72,7 +76,6 @@
mSupplicantState = SupplicantState.UNINITIALIZED;
mRssi = -9999;
mLinkSpeed = -1;
- mIpAddress = 0;
mHiddenSSID = false;
}
@@ -172,12 +175,13 @@
mSupplicantState = state;
}
- void setIpAddress(int address) {
+ void setInetAddress(InetAddress address) {
mIpAddress = address;
}
public int getIpAddress() {
- return mIpAddress;
+ if (mIpAddress == null || mIpAddress instanceof Inet6Address) return 0;
+ return NetworkUtils.inetAddressToInt(mIpAddress);
}
/**
@@ -251,7 +255,12 @@
dest.writeInt(mNetworkId);
dest.writeInt(mRssi);
dest.writeInt(mLinkSpeed);
- dest.writeInt(mIpAddress);
+ if (mIpAddress != null) {
+ dest.writeByte((byte)1);
+ dest.writeByteArray(mIpAddress.getAddress());
+ } else {
+ dest.writeByte((byte)0);
+ }
dest.writeString(getSSID());
dest.writeString(mBSSID);
dest.writeString(mMacAddress);
@@ -266,7 +275,11 @@
info.setNetworkId(in.readInt());
info.setRssi(in.readInt());
info.setLinkSpeed(in.readInt());
- info.setIpAddress(in.readInt());
+ if (in.readByte() == 1) {
+ try {
+ info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
+ } catch (UnknownHostException e) {}
+ }
info.setSSID(in.readString());
info.mBSSID = in.readString();
info.mMacAddress = in.readString();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index d05918f..0807a24 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -24,6 +24,7 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.WorkSource;
+import android.os.Messenger;
import java.util.List;
@@ -60,7 +61,7 @@
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.
* Another extra provides the previous state, if available.
- *
+ *
* @see #EXTRA_WIFI_STATE
* @see #EXTRA_PREVIOUS_WIFI_STATE
*/
@@ -71,7 +72,7 @@
* The lookup key for an int that indicates whether Wi-Fi is enabled,
* disabled, enabling, disabling, or unknown. Retrieve it with
* {@link android.content.Intent#getIntExtra(String,int)}.
- *
+ *
* @see #WIFI_STATE_DISABLED
* @see #WIFI_STATE_DISABLING
* @see #WIFI_STATE_ENABLED
@@ -81,22 +82,22 @@
public static final String EXTRA_WIFI_STATE = "wifi_state";
/**
* The previous Wi-Fi state.
- *
+ *
* @see #EXTRA_WIFI_STATE
*/
public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-
+
/**
* Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
* it finishes successfully.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_DISABLING = 0;
/**
* Wi-Fi is disabled.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -104,14 +105,14 @@
/**
* Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
* it finishes successfully.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_ENABLING = 2;
/**
* Wi-Fi is enabled.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -119,7 +120,7 @@
/**
* Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
* or disabling.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -356,16 +357,6 @@
public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
/**
- * In this Wi-Fi lock mode, Wi-Fi will behave as in the mode
- * {@link #WIFI_MODE_FULL} but it operates at high performance
- * at the expense of power. This mode should be used
- * only when the wifi connection needs to have minimum loss and low
- * latency as it can impact the battery life.
- * @hide
- */
- public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
-
- /**
* In this Wi-Fi lock mode, Wi-Fi will be kept active,
* and will behave normally, i.e., it will attempt to automatically
* establish a connection to a remembered access point that is
@@ -383,10 +374,29 @@
* an application in this mode.
*/
public static final int WIFI_MODE_SCAN_ONLY = 2;
+ /**
+ * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode
+ * {@link #WIFI_MODE_FULL} but it operates at high performance
+ * with minimum packet loss and low packet latency even when
+ * the device screen is off. This mode will consume more power
+ * and hence should be used only when there is a need for such
+ * an active connection.
+ * <p>
+ * An example use case is when a voice connection needs to be
+ * kept active even after the device screen goes off. Holding the
+ * regular {@link #WIFI_MODE_FULL} lock will keep the wifi
+ * connection active, but the connection can be lossy.
+ * Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
+ * duration of the voice call will improve the call quality.
+ * <p>
+ * When there is no support from the hardware, this lock mode
+ * will have the same behavior as {@link #WIFI_MODE_FULL}
+ */
+ public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
/** Anything worse than or equal to this will show 0 bars. */
private static final int MIN_RSSI = -100;
-
+
/** Anything better than or equal to this will show the max bars. */
private static final int MAX_RSSI = -55;
@@ -409,6 +419,22 @@
*/
public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
+ /** List of asyncronous notifications
+ * @hide
+ */
+ public static final int DATA_ACTIVITY_NOTIFICATION = 1;
+
+ //Lowest bit indicates data reception and the second lowest
+ //bit indicates data transmitted
+ /** @hide */
+ public static final int DATA_ACTIVITY_NONE = 0x00;
+ /** @hide */
+ public static final int DATA_ACTIVITY_IN = 0x01;
+ /** @hide */
+ public static final int DATA_ACTIVITY_OUT = 0x02;
+ /** @hide */
+ public static final int DATA_ACTIVITY_INOUT = 0x03;
+
IWifiManager mService;
Handler mHandler;
@@ -469,7 +495,7 @@
* <p/>
* The new network will be marked DISABLED by default. To enable it,
* called {@link #enableNetwork}.
- *
+ *
* @param config the set of variables that describe the configuration,
* contained in a {@link WifiConfiguration} object.
* @return the ID of the newly created network description. This is used in
@@ -509,7 +535,7 @@
/**
* Internal method for doing the RPC that creates a new network description
* or updates an existing one.
- *
+ *
* @param config The possibly sparse object containing the variables that
* are to set or updated in the network description.
* @return the ID of the network on success, {@code -1} on failure.
@@ -696,7 +722,7 @@
* Note: It is possible for this method to change the network IDs of
* existing networks. You should assume the network IDs can be different
* after calling this method.
- *
+ *
* @return {@code true} if the operation succeeded
*/
public boolean saveConfiguration() {
@@ -807,20 +833,20 @@
return WIFI_STATE_UNKNOWN;
}
}
-
+
/**
- * Return whether Wi-Fi is enabled or disabled.
+ * Return whether Wi-Fi is enabled or disabled.
* @return {@code true} if Wi-Fi is enabled
* @see #getWifiState()
*/
public boolean isWifiEnabled() {
return getWifiState() == WIFI_STATE_ENABLED;
}
-
+
/**
* Calculates the level of the signal. This should be used any time a signal
* is being shown.
- *
+ *
* @param rssi The power of the signal measured in RSSI.
* @param numLevels The number of levels to consider in the calculated
* level.
@@ -838,10 +864,10 @@
return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
}
}
-
+
/**
* Compares two signal strengths.
- *
+ *
* @param rssiA The power of the first signal measured in RSSI.
* @param rssiB The power of the second signal measured in RSSI.
* @return Returns <0 if the first signal is weaker than the second signal,
@@ -1106,9 +1132,24 @@
}
/**
+ * Get a reference to WifiService handler. This is used by a client to establish
+ * an AsyncChannel communication with WifiService
+ *
+ * @return Messenger pointing to the WifiService handler
+ * @hide
+ */
+ public Messenger getMessenger() {
+ try {
+ return mService.getMessenger();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Allows an application to keep the Wi-Fi radio awake.
* Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
- * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
+ * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
* applications may hold WifiLocks, and the radio will only be allowed to turn off when no
* WifiLocks are held in any application.
*
@@ -1144,7 +1185,7 @@
* Locks the Wi-Fi radio on until {@link #release} is called.
*
* If this WifiLock is reference-counted, each call to {@code acquire} will increment the
- * reference count, and the radio will remain locked as long as the reference count is
+ * reference count, and the radio will remain locked as long as the reference count is
* above zero.
*
* If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
@@ -1288,9 +1329,10 @@
* Creates a new WifiLock.
*
* @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
- * and {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks.
- * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
- * never shown to the user under normal conditions, but should be descriptive
+ * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for
+ * descriptions of the types of Wi-Fi locks.
+ * @param tag a tag for the WifiLock to identify it in debugging messages. This string is
+ * never shown to the user under normal conditions, but should be descriptive
* enough to identify your application and the specific WifiLock within it, if it
* holds multiple WifiLocks.
*
@@ -1301,7 +1343,7 @@
public WifiLock createWifiLock(int lockType, String tag) {
return new WifiLock(lockType, tag);
}
-
+
/**
* Creates a new WifiLock.
*
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 030048f..39676b0 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -16,8 +16,6 @@
package android.net.wifi;
-import android.net.DhcpInfo;
-
/**
* Native calls for sending requests to the supplicant daemon, and for
* receiving asynchronous events. All methods of the form "xxxxCommand()"
@@ -163,10 +161,6 @@
public native static String startWpsWithPinFromDeviceCommand(String bssid);
- public native static boolean doDhcpRequest(DhcpInfo results);
-
- public native static String getDhcpError();
-
public native static boolean setSuspendOptimizationsCommand(boolean enabled);
public native static boolean setCountryCodeCommand(String countryCode);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e951616..fc42ab8 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -435,10 +435,11 @@
private final IBatteryStats mBatteryStats;
- public WifiStateMachine(Context context) {
+ public WifiStateMachine(Context context, String wlanInterface) {
super(TAG);
mContext = context;
+ mInterfaceName = wlanInterface;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
@@ -449,7 +450,6 @@
mWifiMonitor = new WifiMonitor(this);
mDhcpInfoInternal = new DhcpInfoInternal();
mWifiInfo = new WifiInfo();
- mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
mLinkProperties = new LinkProperties();
@@ -1393,7 +1393,7 @@
sendNetworkStateChangeBroadcast(mLastBssid);
/* Reset data structures */
- mWifiInfo.setIpAddress(0);
+ mWifiInfo.setInetAddress(null);
mWifiInfo.setBSSID(null);
mWifiInfo.setSSID(null);
mWifiInfo.setNetworkId(-1);
@@ -2543,7 +2543,7 @@
synchronized (mDhcpInfoInternal) {
addr = NetworkUtils.numericToInetAddress(mDhcpInfoInternal.ipAddress);
}
- mWifiInfo.setIpAddress(NetworkUtils.inetAddressToInt(addr));
+ mWifiInfo.setInetAddress(addr);
configureLinkProperties();
if (getNetworkDetailedState() == DetailedState.CONNECTED) {
sendLinkConfigurationChangedBroadcast();
@@ -2556,7 +2556,7 @@
transitionTo(mConnectedState);
break;
case CMD_IP_CONFIG_FAILURE:
- mWifiInfo.setIpAddress(0);
+ mWifiInfo.setInetAddress(null);
Log.e(TAG, "IP configuration failed");
/**
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 2aff7ec..07900ae 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -45,7 +45,6 @@
private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
- private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
private LinkProperties mLinkProperties;
@@ -136,40 +135,6 @@
}
/**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- * TODO: needs to go away
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature that is no longer needed.
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- * TODO: needs to go away
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled) {
@@ -215,13 +180,6 @@
}
/**
- * Fetch default gateway address for the network
- */
- public int getDefaultGatewayAddr() {
- return mDefaultGatewayAddr.get();
- }
-
- /**
* Check if default route is set
*/
public boolean isDefaultRouteSet() {