Merge change 1939 into donut
* changes:
Temporarily suppress flaky test LocationManagerProximityTest until test harness support can be rolled out.
diff --git a/Android.mk b/Android.mk
index ca76fb4..bbda5fb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -64,6 +64,8 @@
##
## READ ME: ########################################################
LOCAL_SRC_FILES += \
+ core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
+ core/java/android/accessibilityservice/IEventListener.aidl \
core/java/android/accounts/IAccountsService.aidl \
core/java/android/app/IActivityPendingResult.aidl \
core/java/android/app/IActivityWatcher.aidl \
@@ -106,6 +108,8 @@
core/java/android/os/IPermissionController.aidl \
core/java/android/os/IPowerManager.aidl \
core/java/android/text/IClipboard.aidl \
+ core/java/android/view/accessibility/IAccessibilityManager.aidl \
+ core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \
core/java/android/view/IApplicationToken.aidl \
core/java/android/view/IOnKeyguardExitResult.aidl \
core/java/android/view/IRotationWatcher.aidl \
diff --git a/NOTICE b/NOTICE
index 267a6aa..bb9c5f2 100644
--- a/NOTICE
+++ b/NOTICE
@@ -220,3 +220,54 @@
END OF TERMS AND CONDITIONS
+
+
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+Unicode Data Files include all data files under the directories
+http://www.unicode.org/Public/, http://www.unicode.org/reports/,
+and http://www.unicode.org/cldr/data/ . Unicode Software includes any
+source code published in the Unicode Standard or under the directories
+http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
+http://www.unicode.org/cldr/data/.
+
+NOTICE TO USER: Carefully read the following legal agreement. BY
+DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA
+FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY
+ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF
+THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY,
+DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright © 1991-2008 Unicode, Inc. All rights reserved. Distributed
+under the Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Unicode data files and any associated documentation (the
+"Data Files") or Unicode software and any associated documentation (the
+"Software") to deal in the Data Files or Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, and/or sell copies of the Data Files or Software,
+and to permit persons to whom the Data Files or Software are furnished to
+do so, provided that (a) the above copyright notice(s) and this permission
+notice appear with all copies of the Data Files or Software, (b) both the
+above copyright notice(s) and this permission notice appear in associated
+documentation, and (c) there is clear notice in each modified Data File
+or in the Software as well as in the documentation associated with the
+Data File(s) or Software that the data or software has been modified.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in these Data Files or Software without prior written
+authorization of the copyright holder.
diff --git a/api/1.xml b/api/1.xml
index b196ac7..02e8eac 100644
--- a/api/1.xml
+++ b/api/1.xml
@@ -88531,7 +88531,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="predicates" type="com.android.internal.util.Predicate...">
+<parameter name="predicates" type="com.android.internal.util.Predicate<android.test.suitebuilder.TestMethod>...">
</parameter>
</method>
<method name="build"
@@ -169208,7 +169208,7 @@
>
<parameter name="loader" type="java.lang.ClassLoader">
</parameter>
-<parameter name="interfaces" type="java.lang.Class...">
+<parameter name="interfaces" type="java.lang.Class<?>...">
</parameter>
<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
</exception>
diff --git a/api/2.xml b/api/2.xml
index b9736fe..65e7cec 100644
--- a/api/2.xml
+++ b/api/2.xml
@@ -88575,7 +88575,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="predicates" type="com.android.internal.util.Predicate...">
+<parameter name="predicates" type="com.android.internal.util.Predicate<android.test.suitebuilder.TestMethod>...">
</parameter>
</method>
<method name="build"
@@ -169353,7 +169353,7 @@
>
<parameter name="loader" type="java.lang.ClassLoader">
</parameter>
-<parameter name="interfaces" type="java.lang.Class...">
+<parameter name="interfaces" type="java.lang.Class<?>...">
</parameter>
<exception name="IllegalArgumentException" type="java.lang.IllegalArgumentException">
</exception>
diff --git a/api/current.xml b/api/current.xml
index 623b986..b743b03 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -870,17 +870,6 @@
visibility="public"
>
</field>
-<field name="SDCARD_WRITE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""android.permission.SDCARD_WRITE""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="SEND_SMS"
type="java.lang.String"
transient="false"
@@ -1167,6 +1156,17 @@
visibility="public"
>
</field>
+<field name="WRITE_SDCARD"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.permission.WRITE_SDCARD""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="WRITE_SECURE_SETTINGS"
type="java.lang.String"
transient="false"
@@ -2550,6 +2550,17 @@
visibility="public"
>
</field>
+<field name="contentDescription"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843379"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="cropToPadding"
type="int"
transient="false"
@@ -12656,6 +12667,270 @@
</constructor>
</class>
</package>
+<package name="android.accessibilityservice"
+>
+<class name="AccessibilityService"
+ extends="android.app.Service"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccessibilityService"
+ type="android.accessibilityservice.AccessibilityService"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="onAccessibilityEvent"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
+<method name="onBind"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+</method>
+<method name="onInterrupt"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onServiceConnected"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="setServiceInfo"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="info" type="android.accessibilityservice.AccessibilityServiceInfo">
+</parameter>
+</method>
+<field name="SERVICE_INTERFACE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.accessibilityservice.AccessibilityService""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccessibilityServiceInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="AccessibilityServiceInfo"
+ type="android.accessibilityservice.AccessibilityServiceInfo"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="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>
+<field name="DEFAULT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEEDBACK_AUDIBLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEEDBACK_GENERIC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEEDBACK_HAPTIC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEEDBACK_SPOKEN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FEEDBACK_VISUAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="eventTypes"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="feedbackType"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="flags"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="notificationTimeout"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="packageNames"
+ type="java.lang.String[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+</package>
<package name="android.app"
>
<class name="Activity"
@@ -12764,6 +13039,19 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
+<method name="dispatchPopulateAccessibilityEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
<method name="dispatchTouchEvent"
return="boolean"
abstract="false"
@@ -16759,6 +17047,19 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
+<method name="dispatchPopulateAccessibilityEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
<method name="dispatchTouchEvent"
return="boolean"
abstract="false"
@@ -21839,219 +22140,6 @@
</field>
</class>
</package>
-<package name="android.backup"
->
-<class name="BackupDataOutput"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BackupDataOutput"
- type="android.backup.BackupDataOutput"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="fd" type="java.io.FileDescriptor">
-</parameter>
-</constructor>
-<method name="close"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="flush"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="buffer" type="byte[]">
-</parameter>
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="oneByte" type="int">
-</parameter>
-</method>
-<method name="write"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="buffer" type="byte[]">
-</parameter>
-<parameter name="offset" type="int">
-</parameter>
-<parameter name="count" type="int">
-</parameter>
-</method>
-<method name="writeKey"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="key" type="java.lang.String">
-</parameter>
-</method>
-<method name="writeOperation"
- return="void"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="op" type="int">
-</parameter>
-</method>
-<field name="OP_DELETE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="OP_UPDATE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="FileBackupHelper"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="FileBackupHelper"
- type="android.backup.FileBackupHelper"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="performBackup"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="oldSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="data" type="android.backup.BackupDataOutput">
-</parameter>
-<parameter name="files" type="java.lang.String[]">
-</parameter>
-</method>
-</class>
-<class name="SharedPreferencesBackupHelper"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="SharedPreferencesBackupHelper"
- type="android.backup.SharedPreferencesBackupHelper"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="performBackup"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="oldSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="newSnapshot" type="android.os.ParcelFileDescriptor">
-</parameter>
-<parameter name="data" type="android.backup.BackupDataOutput">
-</parameter>
-<parameter name="prefGroups" type="java.lang.String[]">
-</parameter>
-</method>
-</class>
-</package>
<package name="android.content"
>
<class name="ActivityNotFoundException"
@@ -25187,6 +25275,17 @@
<parameter name="receiver" type="android.content.BroadcastReceiver">
</parameter>
</method>
+<field name="ACCESSIBILITY_SERVICE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessibility""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTIVITY_SERVICE"
type="java.lang.String"
transient="false"
@@ -31900,22 +31999,11 @@
visibility="public"
>
</field>
-<field name="FLAG_TARGETS_SDK"
- type="int"
- transient="false"
- volatile="false"
- value="256"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="FLAG_TEST_ONLY"
type="int"
transient="false"
volatile="false"
- value="512"
+ value="256"
static="true"
final="true"
deprecated="not deprecated"
@@ -32055,6 +32143,16 @@
visibility="public"
>
</field>
+<field name="targetSdkVersion"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="taskAffinity"
type="java.lang.String"
transient="false"
@@ -33222,8 +33320,6 @@
>
<parameter name="packageName" type="java.lang.String">
</parameter>
-<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
-</exception>
</method>
<method name="getNameForUid"
return="java.lang.String"
@@ -33651,6 +33747,23 @@
<parameter name="flags" type="int">
</parameter>
</method>
+<method name="resolveActivity"
+ return="android.content.pm.ResolveInfo"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+</method>
<method name="resolveContentProvider"
return="android.content.pm.ProviderInfo"
abstract="true"
@@ -85888,6 +86001,28 @@
visibility="public"
>
</field>
+<field name="CUR_DEVELOPMENT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10000"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DONUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10000"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Bundle"
extends="java.lang.Object"
@@ -102081,6 +102216,17 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
+<field name="ACCESSIBILITY_ENABLED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessibility_enabled""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ADB_ENABLED"
type="java.lang.String"
transient="false"
@@ -102179,6 +102325,17 @@
visibility="public"
>
</field>
+<field name="ENABLED_ACCESSIBILITY_SERVICES"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""enabled_accessibility_services""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ENABLED_INPUT_METHODS"
type="java.lang.String"
transient="false"
@@ -111695,8 +111852,6 @@
>
<parameter name="packageName" type="java.lang.String">
</parameter>
-<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
-</exception>
</method>
<method name="getNameForUid"
return="java.lang.String"
@@ -112106,6 +112261,23 @@
</parameter>
<parameter name="flags" type="int">
</parameter>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+</method>
+<method name="resolveActivity"
+ return="android.content.pm.ResolveInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
</method>
<method name="resolveContentProvider"
return="android.content.pm.ProviderInfo"
@@ -134788,6 +134960,8 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.view.accessibility.AccessibilityEventSource">
+</implements>
<implements name="android.graphics.drawable.Drawable.Callback">
</implements>
<implements name="android.view.KeyEvent.Callback">
@@ -134843,6 +135017,23 @@
<parameter name="direction" type="int">
</parameter>
</method>
+<method name="addFocusables"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="views" type="java.util.ArrayList<android.view.View>">
+</parameter>
+<parameter name="direction" type="int">
+</parameter>
+<parameter name="focusableMode" type="int">
+</parameter>
+</method>
<method name="addTouchables"
return="void"
abstract="false"
@@ -135077,6 +135268,19 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
+<method name="dispatchPopulateAccessibilityEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
<method name="dispatchRestoreInstanceState"
return="void"
abstract="false"
@@ -135371,6 +135575,17 @@
visibility="protected"
>
</method>
+<method name="getContentDescription"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getContext"
return="android.content.Context"
abstract="false"
@@ -137327,6 +137542,32 @@
<parameter name="y" type="int">
</parameter>
</method>
+<method name="sendAccessibilityEvent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventType" type="int">
+</parameter>
+</method>
+<method name="sendAccessibilityEventUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
<method name="setAnimation"
return="void"
abstract="false"
@@ -137392,6 +137633,19 @@
<parameter name="clickable" type="boolean">
</parameter>
</method>
+<method name="setContentDescription"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="contentDescription" type="java.lang.CharSequence">
+</parameter>
+</method>
<method name="setDrawingCacheBackgroundColor"
return="void"
abstract="false"
@@ -138180,6 +138434,28 @@
visibility="protected"
>
</field>
+<field name="FOCUSABLES_ALL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FOCUSABLES_TOUCH_MODE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FOCUSED_SELECTED_STATE_SET"
type="int[]"
transient="false"
@@ -139345,6 +139621,17 @@
<implements name="java.lang.annotation.Annotation">
</implements>
</class>
+<class name="ViewDebug.FlagToString"
+ extends="java.lang.Object"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="java.lang.annotation.Annotation">
+</implements>
+</class>
<class name="ViewDebug.HierarchyTraceType"
extends="java.lang.Enum"
abstract="false"
@@ -142861,6 +143148,19 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
+<method name="dispatchPopulateAccessibilityEvent"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
<method name="dispatchTouchEvent"
return="boolean"
abstract="true"
@@ -144285,6 +144585,698 @@
</field>
</class>
</package>
+<package name="android.view.accessibility"
+>
+<class name="AccessibilityEvent"
+ 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="getAddedCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getBeforeText"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getClassName"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getContentDescription"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrentItemIndex"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEventTime"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEventType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFromIndex"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getItemCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPackageName"
+ return="java.lang.CharSequence"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getParcelableData"
+ return="android.os.Parcelable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getRemovedCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getText"
+ return="java.util.List<java.lang.CharSequence>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="initFromParcel"
+ 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>
+</method>
+<method name="isChecked"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isFullScreen"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isPassword"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="obtain"
+ return="android.view.accessibility.AccessibilityEvent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventType" type="int">
+</parameter>
+</method>
+<method name="obtain"
+ return="android.view.accessibility.AccessibilityEvent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="recycle"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setAddedCount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="addedCount" type="int">
+</parameter>
+</method>
+<method name="setBeforeText"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="beforeText" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setChecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="isChecked" type="boolean">
+</parameter>
+</method>
+<method name="setClassName"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="className" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setContentDescription"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="contentDescription" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setCurrentItemIndex"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="currentItemIndex" type="int">
+</parameter>
+</method>
+<method name="setEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="isEnabled" type="boolean">
+</parameter>
+</method>
+<method name="setEventTime"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventTime" type="long">
+</parameter>
+</method>
+<method name="setEventType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventType" type="int">
+</parameter>
+</method>
+<method name="setFromIndex"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fromIndex" type="int">
+</parameter>
+</method>
+<method name="setFullScreen"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="isFullScreen" type="boolean">
+</parameter>
+</method>
+<method name="setItemCount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="itemCount" type="int">
+</parameter>
+</method>
+<method name="setPackageName"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="packageName" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setParcelableData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parcelableData" type="android.os.Parcelable">
+</parameter>
+</method>
+<method name="setPassword"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="isPassword" type="boolean">
+</parameter>
+</method>
+<method name="setRemovedCount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="removedCount" type="int">
+</parameter>
+</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>
+<field name="INVALID_POSITION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MAX_TEXT_LENGTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="500"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPES_ALL_MASK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_NOTIFICATION_STATE_CHANGED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="64"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_VIEW_CLICKED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_VIEW_FOCUSED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_VIEW_LONG_CLICKED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_VIEW_SELECTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_VIEW_TEXT_CHANGED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_WINDOW_STATE_CHANGED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="32"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="AccessibilityEventSource"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="sendAccessibilityEvent"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="eventType" type="int">
+</parameter>
+</method>
+<method name="sendAccessibilityEventUnchecked"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
+</interface>
+<class name="AccessibilityManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getAccessibilityServiceList"
+ return="java.util.List<android.content.pm.ServiceInfo>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="interrupt"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="sendAccessibilityEvent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.accessibility.AccessibilityEvent">
+</parameter>
+</method>
+</class>
+</package>
<package name="android.view.animation"
>
<class name="AccelerateDecelerateInterpolator"
diff --git a/cmds/am/am b/cmds/am/am
index a5b13f9..c823634 100755
--- a/cmds/am/am
+++ b/cmds/am/am
@@ -3,5 +3,5 @@
#
base=/system
export CLASSPATH=$base/framework/am.jar
-exec app_process $base/bin com.android.commands.am.Am $*
+exec app_process $base/bin com.android.commands.am.Am "$@"
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
new file mode 100644
index 0000000..a3456c7
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import com.android.internal.os.HandlerCaller;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * An accessibility service runs in the background and receives callbacks by the system
+ * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
+ * in the user interface, for example, the focus has changed, a button has been clicked,
+ * etc.
+ * <p>
+ * An accessibility service extends this class and implements its abstract methods. Such
+ * a service is declared as any other service in an AndroidManifest.xml but it must also
+ * specify that it handles the "android.accessibilityservice.AccessibilityService"
+ * {@link android.content.Intent}. Following is an example of such a declaration:
+ * <p>
+ * <code>
+ * <service android:name=".MyAccessibilityService"><br>
+ * <intent-filter><br>
+ * <action android:name="android.accessibilityservice.AccessibilityService" /><br>
+ * </intent-filter><br>
+ * </service><br>
+ * </code>
+ * <p>
+ * The lifecycle of an accessibility service is managed exclusively by the system. Starting
+ * or stopping an accessibility service is triggered by an explicit user action through
+ * enabling or disabling it in the device settings. After the system binds to a service it
+ * calls {@link AccessibilityService#onServiceConnected()}. This method can be
+ * overriden by clients that want to perform post binding setup. An accessibility service
+ * is configured though setting an {@link AccessibilityServiceInfo} by calling
+ * {@link AccessibilityService#setServiceInfo(AccessibilityServiceInfo)}. You can call this
+ * method any time to change the service configuration but it is good practice to do that
+ * in the overriden {@link AccessibilityService#onServiceConnected()}.
+ * <p>
+ * An accessibility service can be registered for events in specific packages to provide a
+ * specific type of feedback and is notified with a certain timeout after the last event
+ * of interest has been fired.
+ * <p>
+ * <b>Notification strategy</b>
+ * <p>
+ * For each feedback type only one accessibility service is notified. Services are notified
+ * in the order of registration. Hence, if two services are registered for the same
+ * feedback type in the same package the first one wins. It is possible however, to
+ * register a service as the default one for a given feedback type. In such a case this
+ * service is invoked if no other service was interested in the event. In other words, default
+ * services do not compete with other services and are notified last regardless of the
+ * registration order. This enables "generic" accessibility services that work reasonably
+ * well with most applications to coexist with "polished" ones that are targeted for
+ * specific applications.
+ * <p>
+ * <b>Event types</b>
+ * <p>
+ * {@link AccessibilityEvent#TYPE_VIEW_CLICKED}
+ * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
+ * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
+ * {@link AccessibilityEvent#TYPE_VIEW_SELECTED}
+ * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
+ * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
+ * {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
+ * <p>
+ * <b>Feedback types</b>
+ * <p>
+ * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
+ * {@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
+ * {@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
+ * {@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
+ * {@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
+ *
+ * @see AccessibilityEvent
+ * @see AccessibilityServiceInfo
+ * @see android.view.accessibility.AccessibilityManager
+ *
+ * Note: The event notification timeout is useful to avoid propagating events to the client
+ * too frequently since this is accomplished via an expensive interprocess call.
+ * One can think of the timeout as a criteria to determine when event generation has
+ * settled down.
+ */
+public abstract class AccessibilityService extends Service {
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ public static final String SERVICE_INTERFACE =
+ "android.accessibilityservice.AccessibilityService";
+
+ private static final String LOG_TAG = "AccessibilityService";
+
+ private AccessibilityServiceInfo mInfo;
+
+ IAccessibilityServiceConnection mConnection;
+
+ /**
+ * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
+ *
+ * @param event An event.
+ */
+ public abstract void onAccessibilityEvent(AccessibilityEvent event);
+
+ /**
+ * Callback for interrupting the accessibility feedback.
+ */
+ public abstract void onInterrupt();
+
+ /**
+ * This method is a part of the {@link AccessibilityService} lifecycle and is
+ * called after the system has successfully bound to the service. If is
+ * convenient to use this method for setting the {@link AccessibilityServiceInfo}.
+ *
+ * @see AccessibilityServiceInfo
+ * @see #setServiceInfo(AccessibilityServiceInfo)
+ */
+ protected void onServiceConnected() {
+
+ }
+
+ /**
+ * Sets the {@link AccessibilityServiceInfo} that describes this service.
+ * <p>
+ * Note: You can call this method any time but the info will be picked up after
+ * the system has bound to this service and when this method is called thereafter.
+ *
+ * @param info The info.
+ */
+ public final void setServiceInfo(AccessibilityServiceInfo info) {
+ mInfo = info;
+ sendServiceInfo();
+ }
+
+ /**
+ * Sets the {@link AccessibilityServiceInfo} for this service if the latter is
+ * properly set and there is an {@link IAccessibilityServiceConnection} to the
+ * AccessibilityManagerService.
+ */
+ private void sendServiceInfo() {
+ if (mInfo != null && mConnection != null) {
+ try {
+ mConnection.setServiceInfo(mInfo);
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
+ }
+ }
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return new IEventListenerWrapper(this);
+ }
+
+ /**
+ * Implements the internal {@link IEventListener} interface to convert
+ * incoming calls to it back to calls on an {@link AccessibilityService}.
+ */
+ class IEventListenerWrapper extends IEventListener.Stub
+ implements HandlerCaller.Callback {
+
+ private static final int DO_SET_SET_CONNECTION = 10;
+ private static final int DO_ON_INTERRUPT = 20;
+ private static final int DO_ON_ACCESSIBILITY_EVENT = 30;
+
+ private final HandlerCaller mCaller;
+
+ private AccessibilityService mTarget;
+
+ public IEventListenerWrapper(AccessibilityService context) {
+ mTarget = context;
+ mCaller = new HandlerCaller(context, this);
+ }
+
+ public void setConnection(IAccessibilityServiceConnection connection) {
+ Message message = mCaller.obtainMessageO(DO_SET_SET_CONNECTION, connection);
+ mCaller.sendMessage(message);
+ }
+
+ public void onInterrupt() {
+ Message message = mCaller.obtainMessage(DO_ON_INTERRUPT);
+ mCaller.sendMessage(message);
+ }
+
+ public void onAccessibilityEvent(AccessibilityEvent event) {
+ Message message = mCaller.obtainMessageO(DO_ON_ACCESSIBILITY_EVENT, event);
+ mCaller.sendMessage(message);
+ }
+
+ public void executeMessage(Message message) {
+ switch (message.what) {
+ case DO_ON_ACCESSIBILITY_EVENT :
+ AccessibilityEvent event = (AccessibilityEvent) message.obj;
+ mTarget.onAccessibilityEvent(event);
+ event.recycle();
+ return;
+ case DO_ON_INTERRUPT :
+ mTarget.onInterrupt();
+ return;
+ case DO_SET_SET_CONNECTION :
+ mConnection = ((IAccessibilityServiceConnection) message.obj);
+ mTarget.onServiceConnected();
+ return;
+ default :
+ Log.w(LOG_TAG, "Unknown message type " + message.what);
+ }
+ }
+ }
+}
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl b/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl
new file mode 100644
index 0000000..1f5d385
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+parcelable AccessibilityServiceInfo;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
new file mode 100644
index 0000000..4761f98
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class describes an {@link AccessibilityService}. The system
+ * notifies an {@link AccessibilityService} for
+ * {@link android.view.accessibility.AccessibilityEvent}s
+ * according to the information encapsulated in this class.
+ *
+ * @see AccessibilityService
+ * @see android.view.accessibility.AccessibilityEvent
+ */
+public class AccessibilityServiceInfo implements Parcelable {
+
+ /**
+ * Denotes spoken feedback.
+ */
+ public static final int FEEDBACK_SPOKEN = 0x0000001;
+
+ /**
+ * Denotes haptic feedback.
+ */
+ public static final int FEEDBACK_HAPTIC = 0x0000002;
+
+ /**
+ * Denotes audible (not spoken) feedback.
+ */
+ public static final int FEEDBACK_AUDIBLE = 0x0000004;
+
+ /**
+ * Denotes visual feedback.
+ */
+ public static final int FEEDBACK_VISUAL = 0x0000008;
+
+ /**
+ * Denotes generic feedback.
+ */
+ public static final int FEEDBACK_GENERIC = 0x0000010;
+
+ /**
+ * If an {@link AccessibilityService} is the default for a given type.
+ * Default service is invoked only if no package specific one exists. In case of
+ * more than one package specific service only the earlier registered is notified.
+ */
+ public static final int DEFAULT = 0x0000001;
+
+ /**
+ * The event types an {@link AccessibilityService} is interested in.
+ *
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_ACTIVITY_STARTED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
+ * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
+ */
+ public int eventTypes;
+
+ /**
+ * The package names an {@link AccessibilityService} is interested in. Setting
+ * to null is equivalent to all packages.
+ */
+ public String[] packageNames;
+
+ /**
+ * The feedback type an {@link AccessibilityService} provides.
+ *
+ * @see #FEEDBACK_AUDIBLE
+ * @see #FEEDBACK_GENERIC
+ * @see #FEEDBACK_HAPTIC
+ * @see #FEEDBACK_SPOKEN
+ * @see #FEEDBACK_VISUAL
+ */
+ public int feedbackType;
+
+ /**
+ * The timeout after the most recent event of a given type before an
+ * {@link AccessibilityService} is notified.
+ * <p>
+ * Note: The event notification timeout is useful to avoid propagating events to the client
+ * too frequently since this is accomplished via an expensive interprocess call.
+ * One can think of the timeout as a criteria to determine when event generation has
+ * settled down
+ */
+ public long notificationTimeout;
+
+ /**
+ * This field represents a set of flags used for configuring an
+ * {@link AccessibilityService}.
+ *
+ * @see #DEFAULT
+ */
+ public int flags;
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(eventTypes);
+ parcel.writeStringArray(packageNames);
+ parcel.writeInt(feedbackType);
+ parcel.writeLong(notificationTimeout);
+ parcel.writeInt(flags);
+ }
+
+ /**
+ * @see Parcelable.Creator
+ */
+ public static final Parcelable.Creator<AccessibilityServiceInfo> CREATOR =
+ new Parcelable.Creator<AccessibilityServiceInfo>() {
+ public AccessibilityServiceInfo createFromParcel(Parcel parcel) {
+ AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+ info.eventTypes = parcel.readInt();
+ info.packageNames = parcel.readStringArray();
+ info.feedbackType = parcel.readInt();
+ info.notificationTimeout = parcel.readLong();
+ info.flags = parcel.readInt();
+ return info;
+ }
+
+ public AccessibilityServiceInfo[] newArray(int size) {
+ return new AccessibilityServiceInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
new file mode 100644
index 0000000..7157def
--- /dev/null
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accessibilityservice;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+
+/**
+ * Interface AccessibilityManagerService#Service implements, and passes to an
+ * AccessibilityService so it can dynamically configure how the system handles it.
+ *
+ * @hide
+ */
+oneway interface IAccessibilityServiceConnection {
+
+ void setServiceInfo(in AccessibilityServiceInfo info);
+}
diff --git a/core/java/android/accessibilityservice/IEventListener.aidl b/core/java/android/accessibilityservice/IEventListener.aidl
new file mode 100644
index 0000000..5b849f1
--- /dev/null
+++ b/core/java/android/accessibilityservice/IEventListener.aidl
@@ -0,0 +1,34 @@
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.accessibilityservice;
+
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Top-level interface to accessibility service component (implemented in Service).
+ *
+ * @hide
+ */
+ oneway interface IEventListener {
+
+ void setConnection(in IAccessibilityServiceConnection connection);
+
+ void onAccessibilityEvent(in AccessibilityEvent event);
+
+ void onInterrupt();
+}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9b1f0f9..f9b3d05 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,6 +16,8 @@
package android.app;
+import com.android.internal.policy.PolicyManager;
+
import android.content.ComponentCallbacks;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -32,11 +34,12 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.Handler;
import android.os.IBinder;
+import android.os.RemoteException;
import android.text.Selection;
import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.AttributeSet;
import android.util.Config;
@@ -58,10 +61,10 @@
import android.view.WindowManager;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
+import android.view.ViewGroup.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
-import com.android.internal.policy.PolicyManager;
-
import java.util.ArrayList;
import java.util.HashMap;
@@ -2013,7 +2016,24 @@
}
return onTrackballEvent(ev);
}
-
+
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ event.setClassName(getClass().getName());
+ event.setPackageName(getPackageName());
+
+ LayoutParams params = getWindow().getAttributes();
+ boolean isFullScreen = (params.width == LayoutParams.FILL_PARENT) &&
+ (params.height == LayoutParams.FILL_PARENT);
+ event.setFullScreen(isFullScreen);
+
+ CharSequence title = getTitle();
+ if (!TextUtils.isEmpty(title)) {
+ event.getText().add(title);
+ }
+
+ return true;
+ }
+
/**
* Default implementation of
* {@link android.view.Window.Callback#onCreatePanelView}
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index bb17dc3..2c2310a 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -16,8 +16,11 @@
package android.app;
-import com.google.android.collect.Maps;
+import com.android.internal.policy.PolicyManager;
import com.android.internal.util.XmlUtils;
+import com.google.android.collect.Maps;
+
+import org.xmlpull.v1.XmlPullParserException;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothDevice;
@@ -37,9 +40,9 @@
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageStatsObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageManager;
+import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -68,15 +71,15 @@
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
-import android.os.Looper;
-import android.os.RemoteException;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
+import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.Vibrator;
import android.os.FileUtils.FileStatus;
@@ -87,10 +90,9 @@
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.WindowManagerImpl;
+import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputMethodManager;
-import com.android.internal.policy.PolicyManager;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -100,16 +102,14 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.WeakHashMap;
import java.util.Set;
-import java.util.HashSet;
+import java.util.WeakHashMap;
import java.util.Map.Entry;
-import org.xmlpull.v1.XmlPullParserException;
-
class ReceiverRestrictedContext extends ContextWrapper {
ReceiverRestrictedContext(Context base) {
super(base);
@@ -172,6 +172,7 @@
private Resources.Theme mTheme = null;
private PackageManager mPackageManager;
private NotificationManager mNotificationManager = null;
+ private AccessibilityManager mAccessibilityManager = null;
private ActivityManager mActivityManager = null;
private Context mReceiverRestrictedContext = null;
private SearchManager mSearchManager = null;
@@ -904,6 +905,8 @@
return getNotificationManager();
} else if (KEYGUARD_SERVICE.equals(name)) {
return new KeyguardManager();
+ } else if (ACCESSIBILITY_SERVICE.equals(name)) {
+ return AccessibilityManager.getInstance(this);
} else if (LOCATION_SERVICE.equals(name)) {
return getLocationManager();
} else if (SEARCH_SERVICE.equals(name)) {
@@ -1516,43 +1519,31 @@
throw new NameNotFoundException(packageName);
}
- public Intent getLaunchIntentForPackage(String packageName)
- throws NameNotFoundException {
+ @Override
+ public Intent getLaunchIntentForPackage(String packageName) {
// First see if the package has an INFO activity; the existence of
// such an activity is implied to be the desired front-door for the
// overall package (such as if it has multiple launcher entries).
- Intent intent = getLaunchIntentForPackageCategory(this, packageName,
- Intent.CATEGORY_INFO);
- if (intent != null) {
- return intent;
- }
-
+ Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
+ intentToResolve.addCategory(Intent.CATEGORY_INFO);
+ ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0, packageName);
+
// Otherwise, try to find a main launcher activity.
- return getLaunchIntentForPackageCategory(this, packageName,
- Intent.CATEGORY_LAUNCHER);
- }
-
- // XXX This should be implemented as a call to the package manager,
- // to reduce the work needed.
- static Intent getLaunchIntentForPackageCategory(PackageManager pm,
- String packageName, String category) {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- Intent intentToResolve = new Intent(Intent.ACTION_MAIN, null);
- intentToResolve.addCategory(category);
- final List<ResolveInfo> apps =
- pm.queryIntentActivities(intentToResolve, 0);
- // I wish there were a way to directly get the "main" activity of a
- // package but ...
- for (ResolveInfo app : apps) {
- if (app.activityInfo.packageName.equals(packageName)) {
- intent.setClassName(packageName, app.activityInfo.name);
- return intent;
- }
+ if (resolveInfo == null) {
+ // reuse the intent instance
+ intentToResolve.removeCategory(Intent.CATEGORY_INFO);
+ intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
+ resolveInfo = resolveActivity(intentToResolve, 0, packageName);
}
- return null;
+ if (resolveInfo == null) {
+ return null;
+ }
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setClassName(packageName, resolveInfo.activityInfo.name);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return intent;
}
-
+
@Override
public int[] getPackageGids(String packageName)
throws NameNotFoundException {
@@ -1790,6 +1781,19 @@
}
@Override
+ public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
+ try {
+ return mPM.resolveIntentForPackage(
+ intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ flags,
+ packageName);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @Override
public List<ResolveInfo> queryIntentActivities(Intent intent,
int flags) {
try {
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 863cbcc..78bbb4f 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -46,7 +46,6 @@
private final DatePicker mDatePicker;
private final OnDateSetListener mCallBack;
private final Calendar mCalendar;
- private final java.text.DateFormat mDateFormat;
private final java.text.DateFormat mTitleDateFormat;
private final String[] mWeekDays;
@@ -108,7 +107,6 @@
DateFormatSymbols symbols = new DateFormatSymbols();
mWeekDays = symbols.getShortWeekdays();
- mDateFormat = DateFormat.getMediumDateFormat(context);
mTitleDateFormat = java.text.DateFormat.
getDateInstance(java.text.DateFormat.FULL);
mCalendar = Calendar.getInstance();
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index b09a57f..222fe75 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,32 +16,34 @@
package android.app;
+import com.android.internal.policy.PolicyManager;
+
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.os.Bundle;
import android.util.Config;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.LayoutInflater;
import android.view.Window;
import android.view.WindowManager;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
-
-import com.android.internal.policy.PolicyManager;
+import android.view.ViewGroup.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
import java.lang.ref.WeakReference;
@@ -81,6 +83,7 @@
* {@hide}
*/
protected boolean mCancelable = true;
+
private Message mCancelMessage;
private Message mDismissMessage;
@@ -209,7 +212,9 @@
if (mShowing) {
if (Config.LOGV) Log.v(LOG_TAG,
"[Dialog] start: already showing, ignore");
- if (mDecor != null) mDecor.setVisibility(View.VISIBLE);
+ if (mDecor != null) {
+ mDecor.setVisibility(View.VISIBLE);
+ }
return;
}
@@ -236,7 +241,9 @@
* Hide the dialog, but do not dismiss it.
*/
public void hide() {
- if (mDecor != null) mDecor.setVisibility(View.GONE);
+ if (mDecor != null) {
+ mDecor.setVisibility(View.GONE);
+ }
}
/**
@@ -266,6 +273,7 @@
}
mWindowManager.removeView(mDecor);
+
mDecor = null;
mWindow.closeAllPanels();
onStop();
@@ -280,7 +288,7 @@
Message.obtain(mDismissMessage).sendToTarget();
}
}
-
+
// internal method to make sure mcreated is set properly without requiring
// users to call through to super in onCreate
void dispatchOnCreate(Bundle savedInstanceState) {
@@ -608,6 +616,18 @@
return onTrackballEvent(ev);
}
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ event.setClassName(getClass().getName());
+ event.setPackageName(mContext.getPackageName());
+
+ LayoutParams params = getWindow().getAttributes();
+ boolean isFullScreen = (params.width == LayoutParams.FILL_PARENT) &&
+ (params.height == LayoutParams.FILL_PARENT);
+ event.setFullScreen(isFullScreen);
+
+ return false;
+ }
+
/**
* @see Activity#onCreatePanelView(int)
*/
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index a174843..343380c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -309,11 +309,23 @@
+ appSearchData + ", " + globalSearch + ")");
}
+ // Try to get the searchable info for the provided component (or for global search,
+ // if globalSearch == true).
mSearchable = SearchManager.getSearchableInfo(componentName, globalSearch);
- if (mSearchable == null) {
- // unfortunately, we can't log here. it would be logspam every time the user
- // clicks the "search" key on a non-search app
- return false;
+
+ // If we got back nothing, and it wasn't a request for global search, then try again
+ // for global search, as we'll try to launch that in lieu of any component-specific search.
+ if (!globalSearch && mSearchable == null) {
+ globalSearch = true;
+ mSearchable = SearchManager.getSearchableInfo(componentName, globalSearch);
+
+ // If we still get back null (i.e., there's not even a searchable info available
+ // for global search), then really give up.
+ if (mSearchable == null) {
+ // Unfortunately, we can't log here. it would be logspam every time the user
+ // clicks the "search" key on a non-search app.
+ return false;
+ }
}
mLaunchComponent = componentName;
@@ -1341,7 +1353,7 @@
private SearchDialog mSearchDialog;
public SearchAutoComplete(Context context) {
- super(null);
+ super(context);
mThreshold = getThreshold();
}
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index 7871fb6..26712a1 100755
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -22,7 +22,7 @@
import android.os.Bundle;
/**
- * A conveience class to aid in implementing an AppWidget provider.
+ * A convenience class to aid in implementing an AppWidget provider.
* Everything you can do with AppWidgetProvider, you can do with a regular {@link BroadcastReceiver}.
* AppWidgetProvider merely parses the relevant fields out of the Intent that is received in
* {@link #onReceive(Context,Intent) onReceive(Context,Intent)}, and calls hook methods
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index 6c47f7e..555494e 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -20,6 +20,7 @@
import java.io.FileDescriptor;
+/** @hide */
public class BackupDataOutput {
/* package */ FileDescriptor fd;
diff --git a/core/java/android/backup/BackupService.java b/core/java/android/backup/BackupService.java
index 6ac703a..50a5921 100644
--- a/core/java/android/backup/BackupService.java
+++ b/core/java/android/backup/BackupService.java
@@ -75,9 +75,8 @@
* file. The application should record the final backup state
* here after writing the requested data to dataFd.
*/
- public abstract void onBackup(ParcelFileDescriptor oldState,
- ParcelFileDescriptor data,
- ParcelFileDescriptor newState);
+ public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState);
/**
* The application is being restored from backup, and should replace any
@@ -92,7 +91,7 @@
* file. The application should record the final backup state
* here after restoring its data from dataFd.
*/
- public abstract void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState);
+ public abstract void onRestore(ParcelFileDescriptor /* TODO: BackupDataInput */ data, ParcelFileDescriptor newState);
// ----- Core implementation -----
@@ -117,7 +116,15 @@
ParcelFileDescriptor newState) throws RemoteException {
// !!! TODO - real implementation; for now just invoke the callbacks directly
Log.v("BackupServiceBinder", "doBackup() invoked");
- BackupService.this.onBackup(oldState, data, newState);
+ BackupDataOutput output = new BackupDataOutput(BackupService.this,
+ data.getFileDescriptor());
+ try {
+ BackupService.this.onBackup(oldState, output, newState);
+ } catch (RuntimeException ex) {
+ Log.d("BackupService", "onBackup ("
+ + BackupService.this.getClass().getName() + ") threw", ex);
+ throw ex;
+ }
}
public void doRestore(ParcelFileDescriptor data,
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index 3b2122c..05159dc 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -18,20 +18,24 @@
import android.content.Context;
import android.os.ParcelFileDescriptor;
+import android.util.Log;
import java.io.FileDescriptor;
+/** @hide */
public class FileBackupHelper {
+ private static final String TAG = "FileBackupHelper";
+
/**
- * Based on oldSnapshot, determine which of the files from the application's data directory
- * need to be backed up, write them to the data stream, and fill in newSnapshot with the
+ * Based on oldState, determine which of the files from the application's data directory
+ * need to be backed up, write them to the data stream, and fill in newState with the
* state as it exists now.
*/
public static void performBackup(Context context,
- ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] files) {
+ ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files) {
String basePath = context.getFilesDir().getAbsolutePath();
- performBackup_checked(basePath, oldSnapshot, newSnapshot, data, files);
+ performBackup_checked(basePath, oldState, data, newState, files);
}
/**
@@ -39,30 +43,31 @@
* since it's easier to do that from java.
*/
static void performBackup_checked(String basePath,
- ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] files) {
- if (newSnapshot == null) {
- throw new NullPointerException("newSnapshot==null");
+ ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files) {
+ if (files.length == 0) {
+ return;
}
- if (data == null) {
- throw new NullPointerException("data==null");
+ if (basePath == null) {
+ throw new NullPointerException();
}
+ // oldStateFd can be null
+ FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
if (data.fd == null) {
- throw new NullPointerException("data.fd==null");
+ throw new NullPointerException();
}
- if (files == null) {
- throw new NullPointerException("files==null");
+ FileDescriptor newStateFd = newState.getFileDescriptor();
+ if (newStateFd == null) {
+ throw new NullPointerException();
}
- int err = performBackup_native(basePath, oldSnapshot.getFileDescriptor(),
- newSnapshot.getFileDescriptor(), data.fd, files);
+ int err = performBackup_native(basePath, oldStateFd, data.fd, newStateFd, files);
if (err != 0) {
throw new RuntimeException("Backup failed"); // TODO: more here
}
}
- native private static int performBackup_native(String basePath,
- FileDescriptor oldSnapshot, FileDescriptor newSnapshot,
- FileDescriptor data, String[] files);
+ native private static int performBackup_native(String basePath, FileDescriptor oldState,
+ FileDescriptor data, FileDescriptor newState, String[] files);
}
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index e839bb4..8627f08 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -21,6 +21,7 @@
import java.io.FileDescriptor;
+/** @hide */
public class SharedPreferencesBackupHelper {
public static void performBackup(Context context,
ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
@@ -34,7 +35,7 @@
files[i] = prefGroups[i] + ".xml";
}
- FileBackupHelper.performBackup_checked(basePath, oldSnapshot, newSnapshot, data, files);
+ FileBackupHelper.performBackup_checked(basePath, oldSnapshot, data, newSnapshot, files);
}
}
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index ce6501c..249d9ba 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -147,7 +147,8 @@
@Override
public boolean onCreate() {
if (isTemporary()) throw new IllegalStateException("onCreate() called for temp provider");
- mOpenHelper = new AbstractSyncableContentProvider.DatabaseHelper(getContext(), mDatabaseName);
+ mOpenHelper = new AbstractSyncableContentProvider.DatabaseHelper(getContext(),
+ mDatabaseName);
mSyncState = new SyncStateContentProviderHelper(mOpenHelper);
AccountMonitorListener listener = new AccountMonitorListener() {
@@ -235,76 +236,147 @@
return Collections.emptyList();
}
+ /**
+ * <p>
+ * Call mOpenHelper.getWritableDatabase() and mDb.beginTransaction().
+ * {@link #endTransaction} MUST be called after calling this method.
+ * Those methods should be used like this:
+ * </p>
+ *
+ * <pre class="prettyprint">
+ * boolean successful = false;
+ * beginTransaction();
+ * try {
+ * // Do something related to mDb
+ * successful = true;
+ * return ret;
+ * } finally {
+ * endTransaction(successful);
+ * }
+ * </pre>
+ *
+ * @hide This method is dangerous from the view of database manipulation, though using
+ * this makes batch insertion/update/delete much faster.
+ */
+ public final void beginTransaction() {
+ mDb = mOpenHelper.getWritableDatabase();
+ mDb.beginTransaction();
+ }
+
+ /**
+ * <p>
+ * Call mDb.endTransaction(). If successful is true, try to call
+ * mDb.setTransactionSuccessful() before calling mDb.endTransaction().
+ * This method MUST be used with {@link #beginTransaction()}.
+ * </p>
+ *
+ * @hide This method is dangerous from the view of database manipulation, though using
+ * this makes batch insertion/update/delete much faster.
+ */
+ public final void endTransaction(boolean successful) {
+ try {
+ if (successful) {
+ // setTransactionSuccessful() must be called just once during opening the
+ // transaction.
+ mDb.setTransactionSuccessful();
+ }
+ } finally {
+ mDb.endTransaction();
+ }
+ }
+
@Override
- public final int update(final Uri url, final ContentValues values,
+ public final int update(final Uri uri, final ContentValues values,
final String selection, final String[] selectionArgs) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
+ boolean successful = false;
+ beginTransaction();
try {
- if (isTemporary() && mSyncState.matches(url)) {
- int numRows = mSyncState.asContentProvider().update(
- url, values, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- return numRows;
- }
-
- int result = updateInternal(url, values, selection, selectionArgs);
- mDb.setTransactionSuccessful();
-
- if (!isTemporary() && result > 0) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
-
- return result;
+ int ret = nonTransactionalUpdate(uri, values, selection, selectionArgs);
+ successful = true;
+ return ret;
} finally {
- mDb.endTransaction();
+ endTransaction(successful);
}
}
+ /**
+ * @hide
+ */
+ public final int nonTransactionalUpdate(final Uri uri, final ContentValues values,
+ final String selection, final String[] selectionArgs) {
+ if (isTemporary() && mSyncState.matches(uri)) {
+ int numRows = mSyncState.asContentProvider().update(
+ uri, values, selection, selectionArgs);
+ return numRows;
+ }
+
+ int result = updateInternal(uri, values, selection, selectionArgs);
+ if (!isTemporary() && result > 0) {
+ getContext().getContentResolver().notifyChange(uri, null /* observer */,
+ changeRequiresLocalSync(uri));
+ }
+
+ return result;
+ }
+
@Override
- public final int delete(final Uri url, final String selection,
+ public final int delete(final Uri uri, final String selection,
final String[] selectionArgs) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
+ boolean successful = false;
+ beginTransaction();
try {
- if (isTemporary() && mSyncState.matches(url)) {
- int numRows = mSyncState.asContentProvider().delete(url, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- return numRows;
- }
- int result = deleteInternal(url, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- if (!isTemporary() && result > 0) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
- return result;
+ int ret = nonTransactionalDelete(uri, selection, selectionArgs);
+ successful = true;
+ return ret;
} finally {
- mDb.endTransaction();
+ endTransaction(successful);
}
}
- @Override
- public final Uri insert(final Uri url, final ContentValues values) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
- try {
- if (isTemporary() && mSyncState.matches(url)) {
- Uri result = mSyncState.asContentProvider().insert(url, values);
- mDb.setTransactionSuccessful();
- return result;
- }
- Uri result = insertInternal(url, values);
- mDb.setTransactionSuccessful();
- if (!isTemporary() && result != null) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
- return result;
- } finally {
- mDb.endTransaction();
+ /**
+ * @hide
+ */
+ public final int nonTransactionalDelete(final Uri uri, final String selection,
+ final String[] selectionArgs) {
+ if (isTemporary() && mSyncState.matches(uri)) {
+ int numRows = mSyncState.asContentProvider().delete(uri, selection, selectionArgs);
+ return numRows;
}
+ int result = deleteInternal(uri, selection, selectionArgs);
+ if (!isTemporary() && result > 0) {
+ getContext().getContentResolver().notifyChange(uri, null /* observer */,
+ changeRequiresLocalSync(uri));
+ }
+ return result;
+ }
+
+ @Override
+ public final Uri insert(final Uri uri, final ContentValues values) {
+ boolean successful = false;
+ beginTransaction();
+ try {
+ Uri ret = nonTransactionalInsert(uri, values);
+ successful = true;
+ return ret;
+ } finally {
+ endTransaction(successful);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public final Uri nonTransactionalInsert(final Uri uri, final ContentValues values) {
+ if (isTemporary() && mSyncState.matches(uri)) {
+ Uri result = mSyncState.asContentProvider().insert(uri, values);
+ return result;
+ }
+ Uri result = insertInternal(uri, values);
+ if (!isTemporary() && result != null) {
+ getContext().getContentResolver().notifyChange(uri, null /* observer */,
+ changeRequiresLocalSync(uri));
+ }
+ return result;
}
@Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f2ad248..c328d1614 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1135,6 +1135,15 @@
public static final String NOTIFICATION_SERVICE = "notification";
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.view.accessibility.AccessibilityManager} for giving the user
+ * feedback for UI events through the registered event listeners.
+ *
+ * @see #getSystemService
+ * @see android.view.accessibility.AccessibilityManager
+ */
+ public static final String ACCESSIBILITY_SERVICE = "accessibility";
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.app.NotificationManager} for controlling keyguard.
*
* @see #getSystemService
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 81f72ac..24262f5 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1048,6 +1048,17 @@
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS";
+ /**
+ * Activity Action: The user pressed the "Report" button in the crash/ANR dialog.
+ * This intent is delivered to the package which installed the application, usually
+ * the Market.
+ * <p>Input: No data is specified. The bug report is passed in using
+ * an {@link #EXTRA_BUG_REPORT} field.
+ * <p>Output: Nothing.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_APP_ERROR = "android.intent.action.APP_ERROR";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent broadcast actions (see action variable).
@@ -1780,6 +1791,24 @@
* delivered.
*/
public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
+
+ /**
+ * Used as a parcelable extra field in {@link #ACTION_APP_ERROR}, containing
+ * the bug report.
+ *
+ * @hide
+ */
+ public static final String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
+
+ /**
+ * Used as a string extra field when sending an intent to PackageInstaller to install a
+ * package. Specifies the installer package name; this package will receive the
+ * {@link #ACTION_APP_ERROR} intent.
+ *
+ * @hide
+ */
+ public static final String EXTRA_INSTALLER_PACKAGE_NAME
+ = "android.intent.extra.INSTALLER_PACKAGE_NAME";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 3827849..9c25e73 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -387,8 +387,7 @@
while (i > 0) {
i--;
AuthorityInfo authority = mAuthorities.get(i);
- if (authority.account.equals(account)
- && authority.authority.equals(providerName)) {
+ if (authority.authority.equals(providerName)) {
authority.enabled = sync;
}
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 88ac04c..ad022e7 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -123,13 +123,7 @@
* Value for {@link #flags}: this is set of the application has set
* its android:targetSdkVersion to something >= the current SDK version.
*/
- public static final int FLAG_TARGETS_SDK = 1<<8;
-
- /**
- * Value for {@link #flags}: this is set of the application has set
- * its android:targetSdkVersion to something >= the current SDK version.
- */
- public static final int FLAG_TEST_ONLY = 1<<9;
+ public static final int FLAG_TEST_ONLY = 1<<8;
/**
* Flags associated with the application. Any combination of
@@ -137,7 +131,7 @@
* {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
* {@link #FLAG_ALLOW_TASK_REPARENTING}
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
- * {@link #FLAG_TARGETS_SDK}.
+ * {@link #FLAG_TEST_ONLY}.
*/
public int flags = 0;
@@ -182,6 +176,16 @@
public int[] supportsDensities;
/**
+ * The minimum SDK version this application targets. It may run on earilier
+ * versions, but it knows how to work with any new behavior added at this
+ * version. Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT}
+ * if this is a development build and the app is targeting that. You should
+ * compare that this number is >= the SDK version number at which your
+ * behavior was introduced.
+ */
+ public int targetSdkVersion;
+
+ /**
* When false, indicates that all components within this application are
* considered disabled, regardless of their individually set enabled status.
*/
@@ -200,6 +204,7 @@
pw.println(prefix + "publicSourceDir=" + publicSourceDir);
pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
pw.println(prefix + "dataDir=" + dataDir);
+ pw.println(prefix + "targetSdkVersion=" + targetSdkVersion);
pw.println(prefix + "enabled=" + enabled);
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
@@ -246,6 +251,7 @@
sharedLibraryFiles = orig.sharedLibraryFiles;
dataDir = orig.dataDir;
uid = orig.uid;
+ targetSdkVersion = orig.targetSdkVersion;
enabled = orig.enabled;
manageSpaceActivityName = orig.manageSpaceActivityName;
descriptionRes = orig.descriptionRes;
@@ -276,6 +282,7 @@
dest.writeStringArray(sharedLibraryFiles);
dest.writeString(dataDir);
dest.writeInt(uid);
+ dest.writeInt(targetSdkVersion);
dest.writeInt(enabled ? 1 : 0);
dest.writeString(manageSpaceActivityName);
dest.writeInt(descriptionRes);
@@ -305,6 +312,7 @@
sharedLibraryFiles = source.readStringArray();
dataDir = source.readString();
uid = source.readInt();
+ targetSdkVersion = source.readInt();
enabled = source.readInt() != 0;
manageSpaceActivityName = source.readString();
descriptionRes = source.readInt();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c199619..bb913cd 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -81,6 +81,9 @@
ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);
+ ResolveInfo resolveIntentForPackage(in Intent intent, String resolvedType, int flags,
+ String packageName);
+
List<ResolveInfo> queryIntentActivities(in Intent intent,
String resolvedType, int flags);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3a192f7..eecbce4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -563,9 +563,8 @@
* launch the main activity in the package, or null if the package does
* not contain such an activity.
*/
- public abstract Intent getLaunchIntentForPackage(String packageName)
- throws NameNotFoundException;
-
+ public abstract Intent getLaunchIntentForPackage(String packageName);
+
/**
* Return an array of all of the secondary group-ids that have been
* assigned to a package.
@@ -971,6 +970,23 @@
public abstract ResolveInfo resolveActivity(Intent intent, int flags);
/**
+ * Resolve the intent restricted to a package.
+ * {@see #resolveActivity}
+ *
+ * @param intent An intent containing all of the desired specification
+ * (action, data, type, category, and/or component).
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ * @param packageName Restrict the intent resolution to this package.
+ *
+ * @return Returns a ResolveInfo containing the final activity intent that
+ * was determined to be the best action. Returns null if no
+ * matching activity was found.
+ */
+ public abstract ResolveInfo resolveActivity(Intent intent, int flags, String packageName);
+
+ /**
* Retrieve all activities that can be performed for the given intent.
*
* @param intent The desired intent as per resolveActivity().
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a1c0f48..78462f1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -55,6 +55,30 @@
* {@hide}
*/
public class PackageParser {
+ /** @hide */
+ public static class NewPermissionInfo {
+ public final String name;
+ public final int sdkVersion;
+ public final int fileVersion;
+
+ public NewPermissionInfo(String name, int sdkVersion, int fileVersion) {
+ this.name = name;
+ this.sdkVersion = sdkVersion;
+ this.fileVersion = fileVersion;
+ }
+ }
+
+ /**
+ * List of new permissions that have been added since 1.0.
+ * NOTE: These must be declared in SDK version order, with permissions
+ * added to older SDKs appearing before those added to newer SDKs.
+ * @hide
+ */
+ public static final PackageParser.NewPermissionInfo NEW_PERMISSIONS[] = new PackageParser.NewPermissionInfo[] {
+ new PackageParser.NewPermissionInfo(android.Manifest.permission.WRITE_SDCARD,
+ android.os.Build.VERSION_CODES.DONUT,
+ 0)
+ };
private String mArchiveSourcePath;
private String[] mSeparateProcesses;
@@ -616,7 +640,6 @@
final Package pkg = new Package(pkgName);
boolean foundApp = false;
- boolean targetsSdk = false;
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifest);
@@ -774,11 +797,10 @@
return null;
}
// If the code matches, it definitely targets this SDK.
- targetsSdk = true;
- } else if (targetVers >= mSdkVersion) {
- // If they have explicitly targeted our current version
- // or something after it, then note this.
- targetsSdk = true;
+ pkg.applicationInfo.targetSdkVersion
+ = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
+ } else {
+ pkg.applicationInfo.targetSdkVersion = targetVers;
}
if (minVers > mSdkVersion) {
@@ -824,8 +846,18 @@
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
}
- if (targetsSdk) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_TARGETS_SDK;
+ final int NP = PackageParser.NEW_PERMISSIONS.length;
+ for (int ip=0; ip<NP; ip++) {
+ final PackageParser.NewPermissionInfo npi
+ = PackageParser.NEW_PERMISSIONS[ip];
+ if (pkg.applicationInfo.targetSdkVersion >= npi.sdkVersion) {
+ break;
+ }
+ if (!pkg.requestedPermissions.contains(npi.name)) {
+ Log.i(TAG, "Impliciting adding " + npi.name + " to old pkg "
+ + pkg.packageName);
+ pkg.requestedPermissions.add(npi.name);
+ }
}
if (pkg.usesLibraries.size() > 0) {
@@ -1189,7 +1221,7 @@
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_testOnly,
- true)) {
+ false)) {
ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
}
diff --git a/core/java/android/net/http/CertificateValidatorCache.java b/core/java/android/net/http/CertificateValidatorCache.java
index 54a1dbe..47661d5 100644
--- a/core/java/android/net/http/CertificateValidatorCache.java
+++ b/core/java/android/net/http/CertificateValidatorCache.java
@@ -236,15 +236,17 @@
}
}
- int hashLength = secureHash.length;
- if (secureHash != null && 0 < hashLength) {
- if (hashLength == mHash.length) {
- for (int i = 0; i < hashLength; ++i) {
- if (secureHash[i] != mHash[i]) {
- return false;
+ if (secureHash != null) {
+ int hashLength = secureHash.length;
+ if (0 < hashLength) {
+ if (hashLength == mHash.length) {
+ for (int i = 0; i < hashLength; ++i) {
+ if (secureHash[i] != mHash[i]) {
+ return false;
+ }
}
+ return true;
}
- return true;
}
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 333ba73..8a0fd58 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -61,6 +61,13 @@
*/
public static final int SCAN_WIFI_LOCK = 6;
+ /**
+ * A constant indicating a wifi multicast timer
+ *
+ * {@hide}
+ */
+ public static final int WIFI_MULTICAST_ENABLED = 7;
+
/**
* Include all of the data in the stats, including previously saved data.
*/
@@ -225,9 +232,13 @@
public abstract void noteFullWifiLockReleasedLocked();
public abstract void noteScanWifiLockAcquiredLocked();
public abstract void noteScanWifiLockReleasedLocked();
+ public abstract void noteWifiMulticastEnabledLocked();
+ public abstract void noteWifiMulticastDisabledLocked();
public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which);
public abstract long getScanWifiLockTime(long batteryRealtime, int which);
+ public abstract long getWifiMulticastTime(long batteryRealtime,
+ int which);
/**
* Note that these must match the constants in android.os.LocalPowerManager.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 5487c54..4a4285e 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -87,6 +87,12 @@
*/
public static class VERSION_CODES {
/**
+ * Magic version number for a current development build, which has
+ * not yet turned into an official release.
+ */
+ public static final int CUR_DEVELOPMENT = 10000;
+
+ /**
* October 2008: The original, first, version of Android. Yay!
*/
public static final int BASE = 1;
@@ -98,6 +104,19 @@
* May 2009: Android 1.5.
*/
public static final int CUPCAKE = 3;
+ /**
+ * Current work on "Donut" development branch.
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li> They must explicitly request the
+ * {@link android.Manifest.permission#WRITE_SDCARD} permission to be
+ * able to modify the contents of the SD card. (Apps targeting
+ * earlier versions will always request the permission.)
+ * </ul>
+ */
+ public static final int DONUT = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 9cf7a22..8fcb4d7 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -30,6 +30,10 @@
import java.io.Reader;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
@@ -857,6 +861,17 @@
/**
+ * Equivalent to <code>setFieldsOn(cl, false)</code>.
+ *
+ * @see #setFieldsOn(Class, boolean)
+ *
+ * @hide
+ */
+ public static void setFieldsOn(Class<?> cl) {
+ setFieldsOn(cl, false);
+ }
+
+ /**
* Reflectively sets static fields of a class based on internal debugging
* properties. This method is a no-op if android.util.Config.DEBUG is
* false.
@@ -868,7 +883,7 @@
* Class setup: define a class whose only fields are non-final, static
* primitive types (except for "char") or Strings. In a static block
* after the field definitions/initializations, pass the class to
- * this method, Debug.setFieldsOn(). Example:
+ * this method, Debug.setFieldsOn(). Example:
* <pre>
* package com.example;
*
@@ -880,12 +895,18 @@
* public static String ns = null;
* public static boolean b = false;
* public static int i = 5;
+ * @Debug.DebugProperty
* public static float f = 0.1f;
+ * @@Debug.DebugProperty
* public static double d = 0.5d;
*
* // This MUST appear AFTER all fields are defined and initialized!
* static {
+ * // Sets all the fields
* Debug.setFieldsOn(MyDebugVars.class);
+ *
+ * // Sets only the fields annotated with @Debug.DebugProperty
+ * // Debug.setFieldsOn(MyDebugVars.class, true);
* }
* }
* </pre>
@@ -898,25 +919,31 @@
* {@hide}
*
* @param cl The class to (possibly) modify
+ * @param partial If false, sets all static fields, otherwise, only set
+ * fields with the {@link android.os.Debug.DebugProperty}
+ * annotation
* @throws IllegalArgumentException if any fields are final or non-static,
* or if the type of the field does not match the type of
* the internal debugging property value.
*/
- public static void setFieldsOn(Class<?> cl) {
+ public static void setFieldsOn(Class<?> cl, boolean partial) {
if (Config.DEBUG) {
if (debugProperties != null) {
/* Only look for fields declared directly by the class,
* so we don't mysteriously change static fields in superclasses.
*/
for (Field field : cl.getDeclaredFields()) {
- final String propertyName = cl.getName() + "." + field.getName();
- boolean isStatic = Modifier.isStatic(field.getModifiers());
- boolean isFinal = Modifier.isFinal(field.getModifiers());
- if (!isStatic || isFinal) {
- throw new IllegalArgumentException(propertyName +
- " must be static and non-final");
+ if (!partial || field.getAnnotation(DebugProperty.class) != null) {
+ final String propertyName = cl.getName() + "." + field.getName();
+ boolean isStatic = Modifier.isStatic(field.getModifiers());
+ boolean isFinal = Modifier.isFinal(field.getModifiers());
+
+ if (!isStatic || isFinal) {
+ throw new IllegalArgumentException(propertyName +
+ " must be static and non-final");
+ }
+ modifyFieldIfSet(field, debugProperties, propertyName);
}
- modifyFieldIfSet(field, debugProperties, propertyName);
}
}
} else {
@@ -925,4 +952,15 @@
") called in non-DEBUG build");
}
}
+
+ /**
+ * Annotation to put on fields you want to set with
+ * {@link Debug#setFieldsOn(Class, boolean)}.
+ *
+ * @hide
+ */
+ @Target({ ElementType.FIELD })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface DebugProperty {
+ }
}
diff --git a/core/java/android/pim/EventRecurrence.java b/core/java/android/pim/EventRecurrence.java
index edf69ee..3ea9b4a 100644
--- a/core/java/android/pim/EventRecurrence.java
+++ b/core/java/android/pim/EventRecurrence.java
@@ -408,13 +408,13 @@
private String dayToString(Resources r, int day) {
switch (day) {
- case SU: return r.getString(com.android.internal.R.string.sunday);
- case MO: return r.getString(com.android.internal.R.string.monday);
- case TU: return r.getString(com.android.internal.R.string.tuesday);
- case WE: return r.getString(com.android.internal.R.string.wednesday);
- case TH: return r.getString(com.android.internal.R.string.thursday);
- case FR: return r.getString(com.android.internal.R.string.friday);
- case SA: return r.getString(com.android.internal.R.string.saturday);
+ case SU: return r.getString(com.android.internal.R.string.day_of_week_long_sunday);
+ case MO: return r.getString(com.android.internal.R.string.day_of_week_long_monday);
+ case TU: return r.getString(com.android.internal.R.string.day_of_week_long_tuesday);
+ case WE: return r.getString(com.android.internal.R.string.day_of_week_long_wednesday);
+ case TH: return r.getString(com.android.internal.R.string.day_of_week_long_thursday);
+ case FR: return r.getString(com.android.internal.R.string.day_of_week_long_friday);
+ case SA: return r.getString(com.android.internal.R.string.day_of_week_long_saturday);
default: throw new IllegalArgumentException("bad day argument: " + day);
}
}
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 1e9b7ae..cf5664c 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -16,6 +16,7 @@
package android.preference;
+import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
@@ -23,6 +24,8 @@
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.Checkable;
import android.widget.TextView;
@@ -42,6 +45,9 @@
private CharSequence mSummaryOff;
private boolean mChecked;
+ private boolean mSendAccessibilityEventViewClickedType;
+
+ private AccessibilityManager mAccessibilityManager;
private boolean mDisableDependentsState;
@@ -55,6 +61,9 @@
mDisableDependentsState = a.getBoolean(
com.android.internal.R.styleable.CheckBoxPreference_disableDependentsState, false);
a.recycle();
+
+ mAccessibilityManager =
+ (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
}
public CheckBoxPreference(Context context, AttributeSet attrs) {
@@ -64,14 +73,26 @@
public CheckBoxPreference(Context context) {
this(context, null);
}
-
+
@Override
protected void onBindView(View view) {
super.onBindView(view);
-
+
View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
if (checkboxView != null && checkboxView instanceof Checkable) {
((Checkable) checkboxView).setChecked(mChecked);
+
+ // send an event to announce the value change of the CheckBox and is done here
+ // because clicking a preference does not immediately change the checked state
+ // for example when enabling the WiFi
+ if (mSendAccessibilityEventViewClickedType &&
+ mAccessibilityManager.isEnabled() &&
+ checkboxView.isEnabled()) {
+ mSendAccessibilityEventViewClickedType = false;
+
+ int eventType = AccessibilityEvent.TYPE_VIEW_CLICKED;
+ checkboxView.sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
+ }
}
// Sync the summary view
@@ -85,7 +106,7 @@
summaryView.setText(mSummaryOff);
useDefaultSummary = false;
}
-
+
if (useDefaultSummary) {
final CharSequence summary = getSummary();
if (summary != null) {
@@ -111,6 +132,10 @@
boolean newValue = !isChecked();
+ // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change
+ // not sending
+ mSendAccessibilityEventViewClickedType = true;
+
if (!callChangeListener(newValue)) {
return;
}
@@ -124,10 +149,11 @@
* @param checked The checked state.
*/
public void setChecked(boolean checked) {
+
mChecked = checked;
persistBoolean(checked);
-
+
notifyDependencyChange(shouldDisableDependents());
notifyChanged();
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 3c23db0..f2c275e 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -137,6 +137,8 @@
CRASHES_TRUNCATED,
ELAPSED_REALTIME_SEC,
ELAPSED_UPTIME_SEC,
+ HTTP_REQUEST,
+ HTTP_REUSED,
HTTP_STATUS,
PHONE_GSM_REGISTERED,
PHONE_GPRS_ATTEMPTED,
@@ -351,6 +353,3 @@
}
}
}
-
-
-
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index 3141f1a..84fe184 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -340,27 +340,33 @@
}
/**
+ * @hide Used in vCard parser code.
+ */
+ public static long tryGetMyContactsGroupId(ContentResolver resolver) {
+ Cursor groupsCursor = resolver.query(Groups.CONTENT_URI, GROUPS_PROJECTION,
+ Groups.SYSTEM_ID + "='" + Groups.GROUP_MY_CONTACTS + "'", null, null);
+ if (groupsCursor != null) {
+ try {
+ if (groupsCursor.moveToFirst()) {
+ return groupsCursor.getLong(0);
+ }
+ } finally {
+ groupsCursor.close();
+ }
+ }
+ return 0;
+ }
+
+ /**
* Adds a person to the My Contacts group.
- *
+ *
* @param resolver the resolver to use
* @param personId the person to add to the group
* @return the URI of the group membership row
* @throws IllegalStateException if the My Contacts group can't be found
*/
public static Uri addToMyContactsGroup(ContentResolver resolver, long personId) {
- long groupId = 0;
- Cursor groupsCursor = resolver.query(Groups.CONTENT_URI, GROUPS_PROJECTION,
- Groups.SYSTEM_ID + "='" + Groups.GROUP_MY_CONTACTS + "'", null, null);
- if (groupsCursor != null) {
- try {
- if (groupsCursor.moveToFirst()) {
- groupId = groupsCursor.getLong(0);
- }
- } finally {
- groupsCursor.close();
- }
- }
-
+ long groupId = tryGetMyContactsGroupId(resolver);
if (groupId == 0) {
throw new IllegalStateException("Failed to find the My Contacts group");
}
@@ -869,6 +875,17 @@
public static final int TYPE_OTHER = 3;
/**
+ * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future.
+ */
+ public static final int MOBILE_EMAIL_TYPE_INDEX = 2;
+
+ /**
+ * @hide This is temporal. TYPE_MOBILE should be added to TYPE in the future.
+ * This is not "mobile" but "CELL" since vCard uses it for identifying mobile phone.
+ */
+ public static final String MOBILE_EMAIL_TYPE_NAME = "_AUTO_CELL";
+
+ /**
* The user defined label for the the contact method.
* <P>Type: TEXT</P>
*/
@@ -1005,7 +1022,13 @@
}
} else {
if (!TextUtils.isEmpty(label)) {
- display = label;
+ if (label.toString().equals(MOBILE_EMAIL_TYPE_NAME)) {
+ display =
+ context.getString(
+ com.android.internal.R.string.mobileEmailTypeName);
+ } else {
+ display = label;
+ }
}
}
break;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4dd6524..ed5520d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1905,6 +1905,17 @@
public static final String USE_GOOGLE_MAIL = "use_google_mail";
/**
+ * If accessibility is enabled.
+ */
+ public static final String ACCESSIBILITY_ENABLED = "accessibility_enabled";
+
+ /**
+ * List of the enabled accessibility providers.
+ */
+ public static final String ENABLED_ACCESSIBILITY_SERVICES =
+ "enabled_accessibility_services";
+
+ /**
* Whether to notify the user of open networks.
* <p>
* If not connected and the scan results have an open network, we will
@@ -2160,6 +2171,13 @@
public static final String CHANGED_ACTION =
"com.google.gservices.intent.action.GSERVICES_CHANGED";
+ /**
+ * Intent action to override Gservices for testing. (Requires WRITE_GSERVICES permission.)
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String OVERRIDE_ACTION =
+ "com.google.gservices.intent.action.GSERVICES_OVERRIDE";
+
private static volatile NameValueCache mNameValueCache = null;
private static final Object mNameValueCacheLock = new Object();
@@ -3247,4 +3265,3 @@
return "android-" + Long.toHexString(androidId);
}
}
-
diff --git a/core/java/android/syncml/pim/PropertyNode.java b/core/java/android/syncml/pim/PropertyNode.java
index cc52499..983ecb8 100644
--- a/core/java/android/syncml/pim/PropertyNode.java
+++ b/core/java/android/syncml/pim/PropertyNode.java
@@ -17,12 +17,16 @@
package android.syncml.pim;
import android.content.ContentValues;
-import android.util.Log;
+import org.apache.commons.codec.binary.Base64;
+
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
public class PropertyNode {
@@ -52,7 +56,9 @@
public Set<String> propGroupSet;
public PropertyNode() {
+ propName = "";
propValue = "";
+ propValue_vector = new ArrayList<String>();
paramMap = new ContentValues();
paramMap_TYPE = new HashSet<String>();
propGroupSet = new HashSet<String>();
@@ -62,13 +68,21 @@
String propName, String propValue, List<String> propValue_vector,
byte[] propValue_bytes, ContentValues paramMap, Set<String> paramMap_TYPE,
Set<String> propGroupSet) {
- this.propName = propName;
+ if (propName != null) {
+ this.propName = propName;
+ } else {
+ this.propName = "";
+ }
if (propValue != null) {
this.propValue = propValue;
} else {
this.propValue = "";
}
- this.propValue_vector = propValue_vector;
+ if (propValue_vector != null) {
+ this.propValue_vector = propValue_vector;
+ } else {
+ this.propValue_vector = new ArrayList<String>();
+ }
this.propValue_bytes = propValue_bytes;
if (paramMap != null) {
this.paramMap = paramMap;
@@ -117,17 +131,9 @@
// decoded by BASE64 or QUOTED-PRINTABLE. When the size of propValue_vector
// is 1, the encoded value is stored in propValue, so we do not have to
// check it.
- if (propValue_vector != null) {
- // Log.d("@@@", "===" + propValue_vector + ", " + node.propValue_vector);
- return (propValue_vector.equals(node.propValue_vector) ||
- (propValue_vector.size() == 1));
- } else if (node.propValue_vector != null) {
- // Log.d("@@@", "===" + propValue_vector + ", " + node.propValue_vector);
- return (node.propValue_vector.equals(propValue_vector) ||
- (node.propValue_vector.size() == 1));
- } else {
- return true;
- }
+ return (propValue_vector.equals(node.propValue_vector) ||
+ propValue_vector.size() == 1 ||
+ node.propValue_vector.size() == 1);
}
}
@@ -154,4 +160,164 @@
builder.append(propValue);
return builder.toString();
}
+
+ /**
+ * Encode this object into a string which can be decoded.
+ */
+ public String encode() {
+ // PropertyNode#toString() is for reading, not for parsing in the future.
+ // We construct appropriate String here.
+ StringBuilder builder = new StringBuilder();
+ if (propName.length() > 0) {
+ builder.append("propName:[");
+ builder.append(propName);
+ builder.append("],");
+ }
+ int size = propGroupSet.size();
+ if (size > 0) {
+ Set<String> set = propGroupSet;
+ builder.append("propGroup:[");
+ int i = 0;
+ for (String group : set) {
+ // We do not need to double quote groups.
+ // group = 1*(ALPHA / DIGIT / "-")
+ builder.append(group);
+ if (i < size - 1) {
+ builder.append(",");
+ }
+ i++;
+ }
+ builder.append("],");
+ }
+
+ if (paramMap.size() > 0 || paramMap_TYPE.size() > 0) {
+ ContentValues values = paramMap;
+ builder.append("paramMap:[");
+ size = paramMap.size();
+ int i = 0;
+ for (Entry<String, Object> entry : values.valueSet()) {
+ // Assuming param-key does not contain NON-ASCII nor symbols.
+ //
+ // According to vCard 3.0:
+ // param-name = iana-token / x-name
+ builder.append(entry.getKey());
+
+ // param-value may contain any value including NON-ASCIIs.
+ // We use the following replacing rule.
+ // \ -> \\
+ // , -> \,
+ // In String#replaceAll(), "\\\\" means a single backslash.
+ builder.append("=");
+ builder.append(entry.getValue().toString()
+ .replaceAll("\\\\", "\\\\\\\\")
+ .replaceAll(",", "\\\\,"));
+ if (i < size -1) {
+ builder.append(",");
+ }
+ i++;
+ }
+
+ Set<String> set = paramMap_TYPE;
+ size = paramMap_TYPE.size();
+ if (i > 0 && size > 0) {
+ builder.append(",");
+ }
+ i = 0;
+ for (String type : set) {
+ builder.append("TYPE=");
+ builder.append(type
+ .replaceAll("\\\\", "\\\\\\\\")
+ .replaceAll(",", "\\\\,"));
+ if (i < size - 1) {
+ builder.append(",");
+ }
+ i++;
+ }
+ builder.append("],");
+ }
+
+ size = propValue_vector.size();
+ if (size > 0) {
+ builder.append("propValue:[");
+ List<String> list = propValue_vector;
+ for (int i = 0; i < size; i++) {
+ builder.append(list.get(i)
+ .replaceAll("\\\\", "\\\\\\\\")
+ .replaceAll(",", "\\\\,"));
+ if (i < size -1) {
+ builder.append(",");
+ }
+ }
+ builder.append("],");
+ }
+
+ return builder.toString();
+ }
+
+ public static PropertyNode decode(String encodedString) {
+ PropertyNode propertyNode = new PropertyNode();
+ String trimed = encodedString.trim();
+ if (trimed.length() == 0) {
+ return propertyNode;
+ }
+ String[] elems = trimed.split("],");
+
+ for (String elem : elems) {
+ int index = elem.indexOf('[');
+ String name = elem.substring(0, index - 1);
+ Pattern pattern = Pattern.compile("(?<!\\\\),");
+ String[] values = pattern.split(elem.substring(index + 1), -1);
+ if (name.equals("propName")) {
+ propertyNode.propName = values[0];
+ } else if (name.equals("propGroupSet")) {
+ for (String value : values) {
+ propertyNode.propGroupSet.add(value);
+ }
+ } else if (name.equals("paramMap")) {
+ ContentValues paramMap = propertyNode.paramMap;
+ Set<String> paramMap_TYPE = propertyNode.paramMap_TYPE;
+ for (String value : values) {
+ String[] tmp = value.split("=", 2);
+ String mapKey = tmp[0];
+ // \, -> ,
+ // \\ -> \
+ // In String#replaceAll(), "\\\\" means a single backslash.
+ String mapValue =
+ tmp[1].replaceAll("\\\\,", ",").replaceAll("\\\\\\\\", "\\\\");
+ if (mapKey.equalsIgnoreCase("TYPE")) {
+ paramMap_TYPE.add(mapValue);
+ } else {
+ paramMap.put(mapKey, mapValue);
+ }
+ }
+ } else if (name.equals("propValue")) {
+ StringBuilder builder = new StringBuilder();
+ List<String> list = propertyNode.propValue_vector;
+ int length = values.length;
+ for (int i = 0; i < length; i++) {
+ String normValue = values[i]
+ .replaceAll("\\\\,", ",")
+ .replaceAll("\\\\\\\\", "\\\\");
+ list.add(normValue);
+ builder.append(normValue);
+ if (i < length - 1) {
+ builder.append(";");
+ }
+ }
+ propertyNode.propValue = builder.toString();
+ }
+ }
+
+ // At this time, QUOTED-PRINTABLE is already decoded to Java String.
+ // We just need to decode BASE64 String to binary.
+ String encoding = propertyNode.paramMap.getAsString("ENCODING");
+ if (encoding != null &&
+ (encoding.equalsIgnoreCase("BASE64") ||
+ encoding.equalsIgnoreCase("B"))) {
+ propertyNode.propValue_bytes =
+ Base64.decodeBase64(propertyNode.propValue_vector.get(0).getBytes());
+ }
+
+ return propertyNode;
+ }
}
diff --git a/core/java/android/syncml/pim/VBuilderCollection.java b/core/java/android/syncml/pim/VBuilderCollection.java
new file mode 100644
index 0000000..f09c1c4
--- /dev/null
+++ b/core/java/android/syncml/pim/VBuilderCollection.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.syncml.pim;
+
+import java.util.Collection;
+import java.util.List;
+
+public class VBuilderCollection implements VBuilder {
+
+ private final Collection<VBuilder> mVBuilderCollection;
+
+ public VBuilderCollection(Collection<VBuilder> vBuilderCollection) {
+ mVBuilderCollection = vBuilderCollection;
+ }
+
+ public Collection<VBuilder> getVBuilderCollection() {
+ return mVBuilderCollection;
+ }
+
+ public void start() {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.start();
+ }
+ }
+
+ public void end() {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.end();
+ }
+ }
+
+ public void startRecord(String type) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.startRecord(type);
+ }
+ }
+
+ public void endRecord() {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.endRecord();
+ }
+ }
+
+ public void startProperty() {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.startProperty();
+ }
+ }
+
+
+ public void endProperty() {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.endProperty();
+ }
+ }
+
+ public void propertyGroup(String group) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.propertyGroup(group);
+ }
+ }
+
+ public void propertyName(String name) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.propertyName(name);
+ }
+ }
+
+ public void propertyParamType(String type) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.propertyParamType(type);
+ }
+ }
+
+ public void propertyParamValue(String value) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.propertyParamValue(value);
+ }
+ }
+
+ public void propertyValues(List<String> values) {
+ for (VBuilder builder : mVBuilderCollection) {
+ builder.propertyValues(values);
+ }
+ }
+}
diff --git a/core/java/android/syncml/pim/VDataBuilder.java b/core/java/android/syncml/pim/VDataBuilder.java
index 8c67cf5..f6e5b65 100644
--- a/core/java/android/syncml/pim/VDataBuilder.java
+++ b/core/java/android/syncml/pim/VDataBuilder.java
@@ -17,8 +17,10 @@
package android.syncml.pim;
import android.content.ContentValues;
+import android.util.CharsetUtils;
import android.util.Log;
+import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.net.QuotedPrintableCodec;
@@ -26,9 +28,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
-import java.util.Vector;
/**
* Store the parse result to custom datastruct: VNode, PropertyNode
@@ -38,7 +38,13 @@
*/
public class VDataBuilder implements VBuilder {
static private String LOG_TAG = "VDATABuilder";
-
+
+ /**
+ * If there's no other information available, this class uses this charset for encoding
+ * byte arrays.
+ */
+ static public String DEFAULT_CHARSET = "UTF-8";
+
/** type=VNode */
public List<VNode> vNodeList = new ArrayList<VNode>();
private int mNodeListPos = 0;
@@ -47,34 +53,74 @@
private String mCurrentParamType;
/**
- * Assumes that each String can be encoded into byte array using this encoding.
+ * The charset using which VParser parses the text.
*/
- private String mCharset;
+ private String mSourceCharset;
+
+ /**
+ * The charset with which byte array is encoded to String.
+ */
+ private String mTargetCharset;
private boolean mStrictLineBreakParsing;
public VDataBuilder() {
- mCharset = "ISO-8859-1";
- mStrictLineBreakParsing = false;
+ this(VParser.DEFAULT_CHARSET, DEFAULT_CHARSET, false);
}
- public VDataBuilder(String encoding, boolean strictLineBreakParsing) {
- mCharset = encoding;
- mStrictLineBreakParsing = strictLineBreakParsing;
+ public VDataBuilder(String charset, boolean strictLineBreakParsing) {
+ this(null, charset, strictLineBreakParsing);
}
+ /**
+ * @hide sourceCharset is temporal.
+ */
+ public VDataBuilder(String sourceCharset, String targetCharset,
+ boolean strictLineBreakParsing) {
+ if (sourceCharset != null) {
+ mSourceCharset = sourceCharset;
+ } else {
+ mSourceCharset = VParser.DEFAULT_CHARSET;
+ }
+ if (targetCharset != null) {
+ mTargetCharset = targetCharset;
+ } else {
+ mTargetCharset = DEFAULT_CHARSET;
+ }
+ mStrictLineBreakParsing = strictLineBreakParsing;
+ }
+
public void start() {
}
public void end() {
}
+ // Note: I guess that this code assumes the Record may nest like this:
+ // START:VPOS
+ // ...
+ // START:VPOS2
+ // ...
+ // END:VPOS2
+ // ...
+ // END:VPOS
+ //
+ // However the following code has a bug.
+ // When error occurs after calling startRecord(), the entry which is probably
+ // the cause of the error remains to be in vNodeList, while endRecord() is not called.
+ //
+ // I leave this code as is since I'm not familiar with vcalendar specification.
+ // But I believe we should refactor this code in the future.
+ // Until this, the last entry has to be removed when some error occurs.
public void startRecord(String type) {
+
VNode vnode = new VNode();
vnode.parseStatus = 1;
vnode.VName = type;
+ // I feel this should be done in endRecord(), but it cannot be done because of
+ // the reason above.
vNodeList.add(vnode);
- mNodeListPos = vNodeList.size()-1;
+ mNodeListPos = vNodeList.size() - 1;
mCurrentVNode = vNodeList.get(mNodeListPos);
}
@@ -90,15 +136,14 @@
}
public void startProperty() {
- // System.out.println("+ startProperty. ");
+ mCurrentPropNode = new PropertyNode();
}
public void endProperty() {
- // System.out.println("- endProperty. ");
+ mCurrentVNode.propList.add(mCurrentPropNode);
}
public void propertyName(String name) {
- mCurrentPropNode = new PropertyNode();
mCurrentPropNode.propName = name;
}
@@ -122,139 +167,145 @@
mCurrentParamType = null;
}
- private String encodeString(String originalString, String targetEncoding) {
- Charset charset = Charset.forName(mCharset);
+ private String encodeString(String originalString, String targetCharset) {
+ if (mSourceCharset.equalsIgnoreCase(targetCharset)) {
+ return originalString;
+ }
+ Charset charset = Charset.forName(mSourceCharset);
ByteBuffer byteBuffer = charset.encode(originalString);
// byteBuffer.array() "may" return byte array which is larger than
// byteBuffer.remaining(). Here, we keep on the safe side.
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
try {
- return new String(bytes, targetEncoding);
+ return new String(bytes, targetCharset);
} catch (UnsupportedEncodingException e) {
- return null;
+ Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
+ return new String(bytes);
}
}
+ private String handleOneValue(String value, String targetCharset, String encoding) {
+ if (encoding != null) {
+ if (encoding.equals("BASE64") || encoding.equals("B")) {
+ // Assume BASE64 is used only when the number of values is 1.
+ mCurrentPropNode.propValue_bytes =
+ Base64.decodeBase64(value.getBytes());
+ return value;
+ } else if (encoding.equals("QUOTED-PRINTABLE")) {
+ String quotedPrintable = value
+ .replaceAll("= ", " ").replaceAll("=\t", "\t");
+ String[] lines;
+ if (mStrictLineBreakParsing) {
+ lines = quotedPrintable.split("\r\n");
+ } else {
+ StringBuilder builder = new StringBuilder();
+ int length = quotedPrintable.length();
+ ArrayList<String> list = new ArrayList<String>();
+ for (int i = 0; i < length; i++) {
+ char ch = quotedPrintable.charAt(i);
+ if (ch == '\n') {
+ list.add(builder.toString());
+ builder = new StringBuilder();
+ } else if (ch == '\r') {
+ list.add(builder.toString());
+ builder = new StringBuilder();
+ if (i < length - 1) {
+ char nextCh = quotedPrintable.charAt(i + 1);
+ if (nextCh == '\n') {
+ i++;
+ }
+ }
+ } else {
+ builder.append(ch);
+ }
+ }
+ String finalLine = builder.toString();
+ if (finalLine.length() > 0) {
+ list.add(finalLine);
+ }
+ lines = list.toArray(new String[0]);
+ }
+ StringBuilder builder = new StringBuilder();
+ for (String line : lines) {
+ if (line.endsWith("=")) {
+ line = line.substring(0, line.length() - 1);
+ }
+ builder.append(line);
+ }
+ byte[] bytes;
+ try {
+ bytes = builder.toString().getBytes(mSourceCharset);
+ } catch (UnsupportedEncodingException e1) {
+ Log.e(LOG_TAG, "Failed to encode: charset=" + mSourceCharset);
+ bytes = builder.toString().getBytes();
+ }
+
+ try {
+ bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes);
+ } catch (DecoderException e) {
+ Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
+ return "";
+ }
+
+ try {
+ return new String(bytes, targetCharset);
+ } catch (UnsupportedEncodingException e) {
+ Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
+ return new String(bytes);
+ }
+ }
+ // Unknown encoding. Fall back to default.
+ }
+ return encodeString(value, targetCharset);
+ }
+
public void propertyValues(List<String> values) {
+ if (values == null || values.size() == 0) {
+ mCurrentPropNode.propValue_bytes = null;
+ mCurrentPropNode.propValue_vector.clear();
+ mCurrentPropNode.propValue_vector.add("");
+ mCurrentPropNode.propValue = "";
+ return;
+ }
+
ContentValues paramMap = mCurrentPropNode.paramMap;
- String charsetString = paramMap.getAsString("CHARSET");
-
- boolean setupParamValues = false;
- //decode value string to propValue_bytes
- if (paramMap.containsKey("ENCODING")) {
- String encoding = paramMap.getAsString("ENCODING");
- if (encoding.equalsIgnoreCase("BASE64") ||
- encoding.equalsIgnoreCase("B")) {
- if (values.size() > 1) {
- Log.e(LOG_TAG,
- ("BASE64 encoding is used while " +
- "there are multiple values (" + values.size()));
- }
- mCurrentPropNode.propValue_bytes =
- Base64.decodeBase64(values.get(0).
- replaceAll(" ","").replaceAll("\t","").
- replaceAll("\r\n","").
- getBytes());
- }
-
- if(encoding.equalsIgnoreCase("QUOTED-PRINTABLE")){
- // if CHARSET is defined, we translate each String into the Charset.
- List<String> tmpValues = new ArrayList<String>();
- Vector<byte[]> byteVector = new Vector<byte[]>();
- int size = 0;
- try{
- for (String value : values) {
- String quotedPrintable = value
- .replaceAll("= ", " ").replaceAll("=\t", "\t");
- String[] lines;
- if (mStrictLineBreakParsing) {
- lines = quotedPrintable.split("\r\n");
- } else {
- lines = quotedPrintable
- .replace("\r\n", "\n").replace("\r", "\n").split("\n");
- }
- StringBuilder builder = new StringBuilder();
- for (String line : lines) {
- if (line.endsWith("=")) {
- line = line.substring(0, line.length() - 1);
- }
- builder.append(line);
- }
- byte[] bytes = QuotedPrintableCodec.decodeQuotedPrintable(
- builder.toString().getBytes());
- if (charsetString != null) {
- try {
- tmpValues.add(new String(bytes, charsetString));
- } catch (UnsupportedEncodingException e) {
- Log.e(LOG_TAG, "Failed to encode: charset=" + charsetString);
- tmpValues.add(new String(bytes));
- }
- } else {
- tmpValues.add(new String(bytes));
- }
- byteVector.add(bytes);
- size += bytes.length;
- } // for (String value : values) {
- mCurrentPropNode.propValue_vector = tmpValues;
- mCurrentPropNode.propValue = listToString(tmpValues);
-
- mCurrentPropNode.propValue_bytes = new byte[size];
-
- {
- byte[] tmpBytes = mCurrentPropNode.propValue_bytes;
- int index = 0;
- for (byte[] bytes : byteVector) {
- int length = bytes.length;
- for (int i = 0; i < length; i++, index++) {
- tmpBytes[index] = bytes[i];
- }
- }
- }
- setupParamValues = true;
- } catch(Exception e) {
- Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
- }
- } // QUOTED-PRINTABLE
- } // ENCODING
+ String targetCharset = CharsetUtils.nameForDefaultVendor(paramMap.getAsString("CHARSET"));
+ String encoding = paramMap.getAsString("ENCODING");
- if (!setupParamValues) {
- // if CHARSET is defined, we translate each String into the Charset.
- if (charsetString != null) {
- List<String> tmpValues = new ArrayList<String>();
- for (String value : values) {
- String result = encodeString(value, charsetString);
- if (result != null) {
- tmpValues.add(result);
- } else {
- Log.e(LOG_TAG, "Failed to encode: charset=" + charsetString);
- tmpValues.add(value);
- }
- }
- values = tmpValues;
- }
-
- mCurrentPropNode.propValue_vector = values;
- mCurrentPropNode.propValue = listToString(values);
+ if (targetCharset == null || targetCharset.length() == 0) {
+ targetCharset = mTargetCharset;
}
- mCurrentVNode.propList.add(mCurrentPropNode);
+
+ for (String value : values) {
+ mCurrentPropNode.propValue_vector.add(
+ handleOneValue(value, targetCharset, encoding));
+ }
+
+ mCurrentPropNode.propValue = listToString(mCurrentPropNode.propValue_vector);
}
- private String listToString(Collection<String> list){
- StringBuilder typeListB = new StringBuilder();
- for (String type : list) {
- typeListB.append(type).append(";");
+ private String listToString(List<String> list){
+ int size = list.size();
+ if (size > 1) {
+ StringBuilder typeListB = new StringBuilder();
+ for (String type : list) {
+ typeListB.append(type).append(";");
+ }
+ int len = typeListB.length();
+ if (len > 0 && typeListB.charAt(len - 1) == ';') {
+ return typeListB.substring(0, len - 1);
+ }
+ return typeListB.toString();
+ } else if (size == 1) {
+ return list.get(0);
+ } else {
+ return "";
}
- int len = typeListB.length();
- if (len > 0 && typeListB.charAt(len - 1) == ';') {
- return typeListB.substring(0, len - 1);
- }
- return typeListB.toString();
}
public String getResult(){
return null;
}
}
-
diff --git a/core/java/android/syncml/pim/VParser.java b/core/java/android/syncml/pim/VParser.java
index df93f38..57c5f7a 100644
--- a/core/java/android/syncml/pim/VParser.java
+++ b/core/java/android/syncml/pim/VParser.java
@@ -26,6 +26,9 @@
*
*/
abstract public class VParser {
+ // Assume that "iso-8859-1" is able to map "all" 8bit characters to some unicode and
+ // decode the unicode to the original charset. If not, this setting will cause some bug.
+ public static String DEFAULT_CHARSET = "iso-8859-1";
/**
* The buffer used to store input stream
@@ -96,6 +99,20 @@
}
/**
+ * Parse the given stream with the default encoding.
+ *
+ * @param is
+ * The source to parse.
+ * @param builder
+ * The v builder which used to construct data.
+ * @return Return true for success, otherwise false.
+ * @throws IOException
+ */
+ public boolean parse(InputStream is, VBuilder builder) throws IOException {
+ return parse(is, DEFAULT_CHARSET, builder);
+ }
+
+ /**
* Copy the content of input stream and filter the "folding"
*/
protected void setInputStream(InputStream is, String encoding)
diff --git a/core/java/android/syncml/pim/vcard/ContactStruct.java b/core/java/android/syncml/pim/vcard/ContactStruct.java
index 8d9b7fa..afeb5cd 100644
--- a/core/java/android/syncml/pim/vcard/ContactStruct.java
+++ b/core/java/android/syncml/pim/vcard/ContactStruct.java
@@ -16,45 +16,102 @@
package android.syncml.pim.vcard;
-import java.util.List;
+import android.content.AbstractSyncableContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.Contacts;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.Extensions;
+import android.provider.Contacts.GroupMembership;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Photos;
+import android.syncml.pim.PropertyNode;
+import android.syncml.pim.VNode;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
/**
- * The parameter class of VCardCreator.
+ * The parameter class of VCardComposer.
* This class standy by the person-contact in
* Android system, we must use this class instance as parameter to transmit to
- * VCardCreator so that create vCard string.
+ * VCardComposer so that create vCard string.
*/
// TODO: rename the class name, next step
public class ContactStruct {
- public String company;
+ private static final String LOG_TAG = "ContactStruct";
+
+ // Note: phonetic name probably should be "LAST FIRST MIDDLE" for European languages, and
+ // space should be added between each element while it should not be in Japanese.
+ // But unfortunately, we currently do not have the data and are not sure whether we should
+ // support European version of name ordering.
+ //
+ // TODO: Implement the logic described above if we really need European version of
+ // phonetic name handling. Also, adding the appropriate test case of vCard would be
+ // highly appreciated.
+ public static final int NAME_ORDER_TYPE_ENGLISH = 0;
+ public static final int NAME_ORDER_TYPE_JAPANESE = 1;
+
/** MUST exist */
public String name;
+ public String phoneticName;
/** maybe folding */
- public String notes;
+ public List<String> notes = new ArrayList<String>();
/** maybe folding */
public String title;
/** binary bytes of pic. */
public byte[] photoBytes;
- /** mime_type col of images table */
+ /** The type of Photo (e.g. JPEG, BMP, etc.) */
public String photoType;
/** Only for GET. Use addPhoneList() to PUT. */
public List<PhoneData> phoneList;
/** Only for GET. Use addContactmethodList() to PUT. */
public List<ContactMethod> contactmethodList;
+ /** Only for GET. Use addOrgList() to PUT. */
+ public List<OrganizationData> organizationList;
+ /** Only for GET. Use addExtension() to PUT */
+ public Map<String, List<String>> extensionMap;
- public static class PhoneData{
+ // Use organizationList instead when handling ORG.
+ @Deprecated
+ public String company;
+
+ public static class PhoneData {
+ public int type;
/** maybe folding */
public String data;
- public String type;
public String label;
+ public boolean isPrimary;
}
- public static class ContactMethod{
- public String kind;
- public String type;
+ public static class ContactMethod {
+ // Contacts.KIND_EMAIL, Contacts.KIND_POSTAL
+ public int kind;
+ // e.g. Contacts.ContactMethods.TYPE_HOME, Contacts.PhoneColumns.TYPE_HOME
+ // If type == Contacts.PhoneColumns.TYPE_CUSTOM, label is used.
+ public int type;
public String data;
+ // Used only when TYPE is TYPE_CUSTOM.
public String label;
+ public boolean isPrimary;
+ }
+
+ public static class OrganizationData {
+ public int type;
+ public String companyName;
+ public String positionName;
+ public boolean isPrimary;
}
/**
@@ -63,29 +120,841 @@
* @param type type col of content://contacts/phones
* @param label lable col of content://contacts/phones
*/
- public void addPhone(String data, String type, String label){
- if(phoneList == null)
+ public void addPhone(int type, String data, String label, boolean isPrimary){
+ if (phoneList == null) {
phoneList = new ArrayList<PhoneData>();
- PhoneData st = new PhoneData();
- st.data = data;
- st.type = type;
- st.label = label;
- phoneList.add(st);
+ }
+ PhoneData phoneData = new PhoneData();
+ phoneData.type = type;
+
+ StringBuilder builder = new StringBuilder();
+ String trimed = data.trim();
+ int length = trimed.length();
+ for (int i = 0; i < length; i++) {
+ char ch = trimed.charAt(i);
+ if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
+ builder.append(ch);
+ }
+ }
+ phoneData.data = PhoneNumberUtils.formatNumber(builder.toString());
+ phoneData.label = label;
+ phoneData.isPrimary = isPrimary;
+ phoneList.add(phoneData);
}
+
/**
* Add a contactmethod info to contactmethodList.
- * @param data contact data
+ * @param kind integer value defined in Contacts.java
+ * (e.g. Contacts.KIND_EMAIL)
* @param type type col of content://contacts/contact_methods
+ * @param data contact data
+ * @param label extra string used only when kind is Contacts.KIND_CUSTOM.
*/
- public void addContactmethod(String kind, String data, String type,
- String label){
- if(contactmethodList == null)
+ public void addContactmethod(int kind, int type, String data,
+ String label, boolean isPrimary){
+ if (contactmethodList == null) {
contactmethodList = new ArrayList<ContactMethod>();
- ContactMethod st = new ContactMethod();
- st.kind = kind;
- st.data = data;
- st.type = type;
- st.label = label;
- contactmethodList.add(st);
+ }
+ ContactMethod contactMethod = new ContactMethod();
+ contactMethod.kind = kind;
+ contactMethod.type = type;
+ contactMethod.data = data;
+ contactMethod.label = label;
+ contactMethod.isPrimary = isPrimary;
+ contactmethodList.add(contactMethod);
+ }
+
+ /**
+ * Add a Organization info to organizationList.
+ */
+ public void addOrganization(int type, String companyName, String positionName,
+ boolean isPrimary) {
+ if (organizationList == null) {
+ organizationList = new ArrayList<OrganizationData>();
+ }
+ OrganizationData organizationData = new OrganizationData();
+ organizationData.type = type;
+ organizationData.companyName = companyName;
+ organizationData.positionName = positionName;
+ organizationData.isPrimary = isPrimary;
+ organizationList.add(organizationData);
+ }
+
+ public void addExtension(PropertyNode propertyNode) {
+ if (propertyNode.propValue.length() == 0) {
+ return;
+ }
+ // Now store the string into extensionMap.
+ List<String> list;
+ String name = propertyNode.propName;
+ if (extensionMap == null) {
+ extensionMap = new HashMap<String, List<String>>();
+ }
+ if (!extensionMap.containsKey(name)){
+ list = new ArrayList<String>();
+ extensionMap.put(name, list);
+ } else {
+ list = extensionMap.get(name);
+ }
+
+ list.add(propertyNode.encode());
+ }
+
+ private static String getNameFromNProperty(List<String> elems, int nameOrderType) {
+ // Family, Given, Middle, Prefix, Suffix. (1 - 5)
+ int size = elems.size();
+ if (size > 1) {
+ StringBuilder builder = new StringBuilder();
+ boolean builderIsEmpty = true;
+ // Prefix
+ if (size > 3 && elems.get(3).length() > 0) {
+ builder.append(elems.get(3));
+ builderIsEmpty = false;
+ }
+ String first, second;
+ if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
+ first = elems.get(0);
+ second = elems.get(1);
+ } else {
+ first = elems.get(1);
+ second = elems.get(0);
+ }
+ if (first.length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(first);
+ builderIsEmpty = false;
+ }
+ // Middle name
+ if (size > 2 && elems.get(2).length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(elems.get(2));
+ builderIsEmpty = false;
+ }
+ if (second.length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(second);
+ builderIsEmpty = false;
+ }
+ // Suffix
+ if (size > 4 && elems.get(4).length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(elems.get(4));
+ builderIsEmpty = false;
+ }
+ return builder.toString();
+ } else if (size == 1) {
+ return elems.get(0);
+ } else {
+ return "";
+ }
+ }
+
+ public static ContactStruct constructContactFromVNode(VNode node,
+ int nameOrderType) {
+ if (!node.VName.equals("VCARD")) {
+ // Impossible in current implementation. Just for safety.
+ Log.e(LOG_TAG, "Non VCARD data is inserted.");
+ return null;
+ }
+
+ // For name, there are three fields in vCard: FN, N, NAME.
+ // We prefer FN, which is a required field in vCard 3.0 , but not in vCard 2.1.
+ // Next, we prefer NAME, which is defined only in vCard 3.0.
+ // Finally, we use N, which is a little difficult to parse.
+ String fullName = null;
+ String nameFromNProperty = null;
+
+ // Some vCard has "X-PHONETIC-FIRST-NAME", "X-PHONETIC-MIDDLE-NAME", and
+ // "X-PHONETIC-LAST-NAME"
+ String xPhoneticFirstName = null;
+ String xPhoneticMiddleName = null;
+ String xPhoneticLastName = null;
+
+ ContactStruct contact = new ContactStruct();
+
+ // Each Column of four properties has ISPRIMARY field
+ // (See android.provider.Contacts)
+ // If false even after the following loop, we choose the first
+ // entry as a "primary" entry.
+ boolean prefIsSetAddress = false;
+ boolean prefIsSetPhone = false;
+ boolean prefIsSetEmail = false;
+ boolean prefIsSetOrganization = false;
+
+ for (PropertyNode propertyNode: node.propList) {
+ String name = propertyNode.propName;
+
+ if (TextUtils.isEmpty(propertyNode.propValue)) {
+ continue;
+ }
+
+ if (name.equals("VERSION")) {
+ // vCard version. Ignore this.
+ } else if (name.equals("FN")) {
+ fullName = propertyNode.propValue;
+ } else if (name.equals("NAME") && fullName == null) {
+ // Only in vCard 3.0. Use this if FN does not exist.
+ // Though, note that vCard 3.0 requires FN.
+ fullName = propertyNode.propValue;
+ } else if (name.equals("N")) {
+ nameFromNProperty = getNameFromNProperty(propertyNode.propValue_vector,
+ nameOrderType);
+ } else if (name.equals("SORT-STRING")) {
+ contact.phoneticName = propertyNode.propValue;
+ } else if (name.equals("SOUND")) {
+ if (propertyNode.paramMap_TYPE.contains("X-IRMC-N") &&
+ contact.phoneticName == null) {
+ // Some Japanese mobile phones use this field for phonetic name,
+ // since vCard 2.1 does not have "SORT-STRING" type.
+ // Also, in some cases, the field has some ';' in it.
+ // We remove them.
+ StringBuilder builder = new StringBuilder();
+ String value = propertyNode.propValue;
+ int length = value.length();
+ for (int i = 0; i < length; i++) {
+ char ch = value.charAt(i);
+ if (ch != ';') {
+ builder.append(ch);
+ }
+ }
+ contact.phoneticName = builder.toString();
+ } else {
+ contact.addExtension(propertyNode);
+ }
+ } else if (name.equals("ADR")) {
+ List<String> values = propertyNode.propValue_vector;
+ boolean valuesAreAllEmpty = true;
+ for (String value : values) {
+ if (value.length() > 0) {
+ valuesAreAllEmpty = false;
+ break;
+ }
+ }
+ if (valuesAreAllEmpty) {
+ continue;
+ }
+
+ int kind = Contacts.KIND_POSTAL;
+ int type = -1;
+ String label = "";
+ boolean isPrimary = false;
+ for (String typeString : propertyNode.paramMap_TYPE) {
+ if (typeString.equals("PREF") && !prefIsSetAddress) {
+ // Only first "PREF" is considered.
+ prefIsSetAddress = true;
+ isPrimary = true;
+ } else if (typeString.equalsIgnoreCase("HOME")) {
+ type = Contacts.ContactMethodsColumns.TYPE_HOME;
+ label = "";
+ } else if (typeString.equalsIgnoreCase("WORK") ||
+ typeString.equalsIgnoreCase("COMPANY")) {
+ // "COMPANY" seems emitted by Windows Mobile, which is not
+ // specifically supported by vCard 2.1. We assume this is same
+ // as "WORK".
+ type = Contacts.ContactMethodsColumns.TYPE_WORK;
+ label = "";
+ } else if (typeString.equalsIgnoreCase("POSTAL")) {
+ kind = Contacts.KIND_POSTAL;
+ } else if (typeString.equalsIgnoreCase("PARCEL") ||
+ typeString.equalsIgnoreCase("DOM") ||
+ typeString.equalsIgnoreCase("INTL")) {
+ // We do not have a kind or type matching these.
+ // TODO: fix this. We may need to split entries into two.
+ // (e.g. entries for KIND_POSTAL and KIND_PERCEL)
+ } else if (typeString.toUpperCase().startsWith("X-") &&
+ type < 0) {
+ type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
+ label = typeString.substring(2);
+ } else if (type < 0) {
+ // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
+ // emit non-standard types. We do not handle their values now.
+ type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
+ label = typeString;
+ }
+ }
+ // We use "HOME" as default
+ if (type < 0) {
+ type = Contacts.ContactMethodsColumns.TYPE_HOME;
+ }
+
+ // adr-value = 0*6(text-value ";") text-value
+ // ; PO Box, Extended Address, Street, Locality, Region, Postal
+ // ; Code, Country Name
+ String address;
+ List<String> list = propertyNode.propValue_vector;
+ int size = list.size();
+ if (size > 1) {
+ StringBuilder builder = new StringBuilder();
+ boolean builderIsEmpty = true;
+ if (Locale.getDefault().getCountry().equals(Locale.JAPAN.getCountry())) {
+ // In Japan, the order is reversed.
+ for (int i = size - 1; i >= 0; i--) {
+ String addressPart = list.get(i);
+ if (addressPart.length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(addressPart);
+ builderIsEmpty = false;
+ }
+ }
+ } else {
+ for (int i = 0; i < size; i++) {
+ String addressPart = list.get(i);
+ if (addressPart.length() > 0) {
+ if (!builderIsEmpty) {
+ builder.append(' ');
+ }
+ builder.append(addressPart);
+ builderIsEmpty = false;
+ }
+ }
+ }
+ address = builder.toString().trim();
+ } else {
+ address = propertyNode.propValue;
+ }
+ contact.addContactmethod(kind, type, address, label, isPrimary);
+ } else if (name.equals("ORG")) {
+ // vCard specification does not specify other types.
+ int type = Contacts.OrganizationColumns.TYPE_WORK;
+ String companyName = "";
+ String positionName = "";
+ boolean isPrimary = false;
+
+ for (String typeString : propertyNode.paramMap_TYPE) {
+ if (typeString.equals("PREF") && !prefIsSetOrganization) {
+ // vCard specification officially does not have PREF in ORG.
+ // This is just for safety.
+ prefIsSetOrganization = true;
+ isPrimary = true;
+ }
+ // XXX: Should we cope with X- words?
+ }
+
+ List<String> list = propertyNode.propValue_vector;
+ int size = list.size();
+ if (size > 1) {
+ companyName = list.get(0);
+ StringBuilder builder = new StringBuilder();
+ for (int i = 1; i < size; i++) {
+ builder.append(list.get(1));
+ if (i != size - 1) {
+ builder.append(", ");
+ }
+ }
+ positionName = builder.toString();
+ } else if (size == 1) {
+ companyName = propertyNode.propValue;
+ positionName = "";
+ }
+ contact.addOrganization(type, companyName, positionName, isPrimary);
+ } else if (name.equals("TITLE")) {
+ contact.title = propertyNode.propValue;
+ // XXX: What to do this? Isn't ORG enough?
+ contact.addExtension(propertyNode);
+ } else if (name.equals("ROLE")) {
+ // XXX: What to do this? Isn't ORG enough?
+ contact.addExtension(propertyNode);
+ } else if (name.equals("PHOTO")) {
+ // We prefer PHOTO to LOGO.
+ String valueType = propertyNode.paramMap.getAsString("VALUE");
+ if (valueType != null && valueType.equals("URL")) {
+ // TODO: do something.
+ } else {
+ // Assume PHOTO is stored in BASE64. In that case,
+ // data is already stored in propValue_bytes in binary form.
+ // It should be automatically done by VBuilder (VDataBuilder/VCardDatabuilder)
+ contact.photoBytes = propertyNode.propValue_bytes;
+ String type = propertyNode.paramMap.getAsString("TYPE");
+ if (type != null) {
+ contact.photoType = type;
+ }
+ }
+ } else if (name.equals("LOGO")) {
+ // When PHOTO is not available this is not URL,
+ // we use this instead of PHOTO.
+ String valueType = propertyNode.paramMap.getAsString("VALUE");
+ if (valueType != null && valueType.equals("URL")) {
+ // TODO: do something.
+ } else if (contact.photoBytes == null) {
+ contact.photoBytes = propertyNode.propValue_bytes;
+ String type = propertyNode.paramMap.getAsString("TYPE");
+ if (type != null) {
+ contact.photoType = type;
+ }
+ }
+ } else if (name.equals("EMAIL")) {
+ int type = -1;
+ String label = null;
+ boolean isPrimary = false;
+ for (String typeString : propertyNode.paramMap_TYPE) {
+ if (typeString.equals("PREF") && !prefIsSetEmail) {
+ // Only first "PREF" is considered.
+ prefIsSetEmail = true;
+ isPrimary = true;
+ } else if (typeString.equalsIgnoreCase("HOME")) {
+ type = Contacts.ContactMethodsColumns.TYPE_HOME;
+ } else if (typeString.equalsIgnoreCase("WORK")) {
+ type = Contacts.ContactMethodsColumns.TYPE_WORK;
+ } else if (typeString.equalsIgnoreCase("CELL")) {
+ // We do not have Contacts.ContactMethodsColumns.TYPE_MOBILE yet.
+ type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
+ label = Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME;
+ } else if (typeString.toUpperCase().startsWith("X-") &&
+ type < 0) {
+ type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
+ label = typeString.substring(2);
+ } else if (type < 0) {
+ // vCard 3.0 allows iana-token.
+ // We may have INTERNET (specified in vCard spec),
+ // SCHOOL, etc.
+ type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
+ label = typeString;
+ }
+ }
+ // We use "OTHER" as default.
+ if (type < 0) {
+ type = Contacts.ContactMethodsColumns.TYPE_OTHER;
+ }
+ contact.addContactmethod(Contacts.KIND_EMAIL,
+ type, propertyNode.propValue,label, isPrimary);
+ } else if (name.equals("TEL")) {
+ int type = -1;
+ String label = null;
+ boolean isPrimary = false;
+ boolean isFax = false;
+ for (String typeString : propertyNode.paramMap_TYPE) {
+ if (typeString.equals("PREF") && !prefIsSetPhone) {
+ // Only first "PREF" is considered.
+ prefIsSetPhone = true;
+ isPrimary = true;
+ } else if (typeString.equalsIgnoreCase("HOME")) {
+ type = Contacts.PhonesColumns.TYPE_HOME;
+ } else if (typeString.equalsIgnoreCase("WORK")) {
+ type = Contacts.PhonesColumns.TYPE_WORK;
+ } else if (typeString.equalsIgnoreCase("CELL")) {
+ type = Contacts.PhonesColumns.TYPE_MOBILE;
+ } else if (typeString.equalsIgnoreCase("PAGER")) {
+ type = Contacts.PhonesColumns.TYPE_PAGER;
+ } else if (typeString.equalsIgnoreCase("FAX")) {
+ isFax = true;
+ } else if (typeString.equalsIgnoreCase("VOICE") ||
+ typeString.equalsIgnoreCase("MSG")) {
+ // Defined in vCard 3.0. Ignore these because they
+ // conflict with "HOME", "WORK", etc.
+ // XXX: do something?
+ } else if (typeString.toUpperCase().startsWith("X-") &&
+ type < 0) {
+ type = Contacts.PhonesColumns.TYPE_CUSTOM;
+ label = typeString.substring(2);
+ } else if (type < 0){
+ // We may have MODEM, CAR, ISDN, etc...
+ type = Contacts.PhonesColumns.TYPE_CUSTOM;
+ label = typeString;
+ }
+ }
+ // We use "HOME" as default
+ if (type < 0) {
+ type = Contacts.PhonesColumns.TYPE_HOME;
+ }
+ if (isFax) {
+ if (type == Contacts.PhonesColumns.TYPE_HOME) {
+ type = Contacts.PhonesColumns.TYPE_FAX_HOME;
+ } else if (type == Contacts.PhonesColumns.TYPE_WORK) {
+ type = Contacts.PhonesColumns.TYPE_FAX_WORK;
+ }
+ }
+
+ contact.addPhone(type, propertyNode.propValue, label, isPrimary);
+ } else if (name.equals("NOTE")) {
+ contact.notes.add(propertyNode.propValue);
+ } else if (name.equals("BDAY")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("URL")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("REV")) {
+ // Revision of this VCard entry. I think we can ignore this.
+ contact.addExtension(propertyNode);
+ } else if (name.equals("UID")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("KEY")) {
+ // Type is X509 or PGP? I don't know how to handle this...
+ contact.addExtension(propertyNode);
+ } else if (name.equals("MAILER")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("TZ")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("GEO")) {
+ contact.addExtension(propertyNode);
+ } else if (name.equals("NICKNAME")) {
+ // vCard 3.0 only.
+ contact.addExtension(propertyNode);
+ } else if (name.equals("CLASS")) {
+ // vCard 3.0 only.
+ // e.g. CLASS:CONFIDENTIAL
+ contact.addExtension(propertyNode);
+ } else if (name.equals("PROFILE")) {
+ // VCard 3.0 only. Must be "VCARD". I think we can ignore this.
+ contact.addExtension(propertyNode);
+ } else if (name.equals("CATEGORIES")) {
+ // VCard 3.0 only.
+ // e.g. CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY
+ contact.addExtension(propertyNode);
+ } else if (name.equals("SOURCE")) {
+ // VCard 3.0 only.
+ contact.addExtension(propertyNode);
+ } else if (name.equals("PRODID")) {
+ // VCard 3.0 only.
+ // To specify the identifier for the product that created
+ // the vCard object.
+ contact.addExtension(propertyNode);
+ } else if (name.equals("X-PHONETIC-FIRST-NAME")) {
+ xPhoneticFirstName = propertyNode.propValue;
+ } else if (name.equals("X-PHONETIC-MIDDLE-NAME")) {
+ xPhoneticMiddleName = propertyNode.propValue;
+ } else if (name.equals("X-PHONETIC-LAST-NAME")) {
+ xPhoneticLastName = propertyNode.propValue;
+ } else {
+ // Unknown X- words and IANA token.
+ contact.addExtension(propertyNode);
+ }
+ }
+
+ if (fullName != null) {
+ contact.name = fullName;
+ } else if(nameFromNProperty != null) {
+ contact.name = nameFromNProperty;
+ } else {
+ contact.name = "";
+ }
+
+ if (contact.phoneticName == null &&
+ (xPhoneticFirstName != null || xPhoneticMiddleName != null ||
+ xPhoneticLastName != null)) {
+ // Note: In Europe, this order should be "LAST FIRST MIDDLE". See the comment around
+ // NAME_ORDER_TYPE_* for more detail.
+ String first;
+ String second;
+ if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
+ first = xPhoneticLastName;
+ second = xPhoneticFirstName;
+ } else {
+ first = xPhoneticFirstName;
+ second = xPhoneticLastName;
+ }
+ StringBuilder builder = new StringBuilder();
+ if (first != null) {
+ builder.append(first);
+ }
+ if (xPhoneticMiddleName != null) {
+ builder.append(xPhoneticMiddleName);
+ }
+ if (second != null) {
+ builder.append(second);
+ }
+ contact.phoneticName = builder.toString();
+ }
+
+ // Remove unnecessary white spaces.
+ // It is found that some mobile phone emits phonetic name with just one white space
+ // when a user does not specify one.
+ // This logic is effective toward such kind of weird data.
+ if (contact.phoneticName != null) {
+ contact.phoneticName = contact.phoneticName.trim();
+ }
+
+ // If there is no "PREF", we choose the first entries as primary.
+ if (!prefIsSetPhone &&
+ contact.phoneList != null &&
+ contact.phoneList.size() > 0) {
+ contact.phoneList.get(0).isPrimary = true;
+ }
+
+ if (!prefIsSetAddress && contact.contactmethodList != null) {
+ for (ContactMethod contactMethod : contact.contactmethodList) {
+ if (contactMethod.kind == Contacts.KIND_POSTAL) {
+ contactMethod.isPrimary = true;
+ break;
+ }
+ }
+ }
+ if (!prefIsSetEmail && contact.contactmethodList != null) {
+ for (ContactMethod contactMethod : contact.contactmethodList) {
+ if (contactMethod.kind == Contacts.KIND_EMAIL) {
+ contactMethod.isPrimary = true;
+ break;
+ }
+ }
+ }
+ if (!prefIsSetOrganization &&
+ contact.organizationList != null &&
+ contact.organizationList.size() > 0) {
+ contact.organizationList.get(0).isPrimary = true;
+ }
+
+ return contact;
+ }
+
+ public String displayString() {
+ if (name.length() > 0) {
+ return name;
+ }
+ if (contactmethodList != null && contactmethodList.size() > 0) {
+ for (ContactMethod contactMethod : contactmethodList) {
+ if (contactMethod.kind == Contacts.KIND_EMAIL && contactMethod.isPrimary) {
+ return contactMethod.data;
+ }
+ }
+ }
+ if (phoneList != null && phoneList.size() > 0) {
+ for (PhoneData phoneData : phoneList) {
+ if (phoneData.isPrimary) {
+ return phoneData.data;
+ }
+ }
+ }
+ return "";
+ }
+
+ private void pushIntoContentProviderOrResolver(Object contentSomething,
+ long myContactsGroupId) {
+ ContentResolver resolver = null;
+ AbstractSyncableContentProvider provider = null;
+ if (contentSomething instanceof ContentResolver) {
+ resolver = (ContentResolver)contentSomething;
+ } else if (contentSomething instanceof AbstractSyncableContentProvider) {
+ provider = (AbstractSyncableContentProvider)contentSomething;
+ } else {
+ Log.e(LOG_TAG, "Unsupported object came.");
+ return;
+ }
+
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(People.NAME, name);
+ contentValues.put(People.PHONETIC_NAME, phoneticName);
+
+ if (notes.size() > 1) {
+ StringBuilder builder = new StringBuilder();
+ for (String note : notes) {
+ builder.append(note);
+ builder.append("\n");
+ }
+ contentValues.put(People.NOTES, builder.toString());
+ } else if (notes.size() == 1){
+ contentValues.put(People.NOTES, notes.get(0));
+ }
+
+ Uri personUri;
+ long personId = 0;
+ if (resolver != null) {
+ personUri = Contacts.People.createPersonInMyContactsGroup(
+ resolver, contentValues);
+ if (personUri != null) {
+ personId = ContentUris.parseId(personUri);
+ }
+ } else {
+ personUri = provider.nonTransactionalInsert(People.CONTENT_URI, contentValues);
+ if (personUri != null) {
+ personId = ContentUris.parseId(personUri);
+ ContentValues values = new ContentValues();
+ values.put(GroupMembership.PERSON_ID, personId);
+ values.put(GroupMembership.GROUP_ID, myContactsGroupId);
+ Uri resultUri = provider.nonTransactionalInsert(
+ GroupMembership.CONTENT_URI, values);
+ if (resultUri == null) {
+ Log.e(LOG_TAG, "Faild to insert the person to MyContact.");
+ provider.nonTransactionalDelete(personUri, null, null);
+ personUri = null;
+ }
+ }
+ }
+
+ if (personUri == null) {
+ Log.e(LOG_TAG, "Failed to create the contact.");
+ return;
+ }
+
+ if (photoBytes != null) {
+ if (resolver != null) {
+ People.setPhotoData(resolver, personUri, photoBytes);
+ } else {
+ Uri photoUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
+ ContentValues values = new ContentValues();
+ values.put(Photos.DATA, photoBytes);
+ provider.update(photoUri, values, null, null);
+ }
+ }
+
+ long primaryPhoneId = -1;
+ if (phoneList != null && phoneList.size() > 0) {
+ for (PhoneData phoneData : phoneList) {
+ ContentValues values = new ContentValues();
+ values.put(Contacts.PhonesColumns.TYPE, phoneData.type);
+ if (phoneData.type == Contacts.PhonesColumns.TYPE_CUSTOM) {
+ values.put(Contacts.PhonesColumns.LABEL, phoneData.label);
+ }
+ // Already formatted.
+ values.put(Contacts.PhonesColumns.NUMBER, phoneData.data);
+
+ // Not sure about Contacts.PhonesColumns.NUMBER_KEY ...
+ values.put(Contacts.PhonesColumns.ISPRIMARY, 1);
+ values.put(Contacts.Phones.PERSON_ID, personId);
+ Uri phoneUri;
+ if (resolver != null) {
+ phoneUri = resolver.insert(Phones.CONTENT_URI, values);
+ } else {
+ phoneUri = provider.nonTransactionalInsert(Phones.CONTENT_URI, values);
+ }
+ if (phoneData.isPrimary) {
+ primaryPhoneId = Long.parseLong(phoneUri.getLastPathSegment());
+ }
+ }
+ }
+
+ long primaryOrganizationId = -1;
+ if (organizationList != null && organizationList.size() > 0) {
+ for (OrganizationData organizationData : organizationList) {
+ ContentValues values = new ContentValues();
+ // Currently, we do not use TYPE_CUSTOM.
+ values.put(Contacts.OrganizationColumns.TYPE,
+ organizationData.type);
+ values.put(Contacts.OrganizationColumns.COMPANY,
+ organizationData.companyName);
+ values.put(Contacts.OrganizationColumns.TITLE,
+ organizationData.positionName);
+ values.put(Contacts.OrganizationColumns.ISPRIMARY, 1);
+ values.put(Contacts.OrganizationColumns.PERSON_ID, personId);
+
+ Uri organizationUri;
+ if (resolver != null) {
+ organizationUri = resolver.insert(Organizations.CONTENT_URI, values);
+ } else {
+ organizationUri = provider.nonTransactionalInsert(
+ Organizations.CONTENT_URI, values);
+ }
+ if (organizationData.isPrimary) {
+ primaryOrganizationId = Long.parseLong(organizationUri.getLastPathSegment());
+ }
+ }
+ }
+
+ long primaryEmailId = -1;
+ if (contactmethodList != null && contactmethodList.size() > 0) {
+ for (ContactMethod contactMethod : contactmethodList) {
+ ContentValues values = new ContentValues();
+ values.put(Contacts.ContactMethodsColumns.KIND, contactMethod.kind);
+ values.put(Contacts.ContactMethodsColumns.TYPE, contactMethod.type);
+ if (contactMethod.type == Contacts.ContactMethodsColumns.TYPE_CUSTOM) {
+ values.put(Contacts.ContactMethodsColumns.LABEL, contactMethod.label);
+ }
+ values.put(Contacts.ContactMethodsColumns.DATA, contactMethod.data);
+ values.put(Contacts.ContactMethodsColumns.ISPRIMARY, 1);
+ values.put(Contacts.ContactMethods.PERSON_ID, personId);
+
+ if (contactMethod.kind == Contacts.KIND_EMAIL) {
+ Uri emailUri;
+ if (resolver != null) {
+ emailUri = resolver.insert(ContactMethods.CONTENT_URI, values);
+ } else {
+ emailUri = provider.nonTransactionalInsert(
+ ContactMethods.CONTENT_URI, values);
+ }
+ if (contactMethod.isPrimary) {
+ primaryEmailId = Long.parseLong(emailUri.getLastPathSegment());
+ }
+ } else { // probably KIND_POSTAL
+ if (resolver != null) {
+ resolver.insert(ContactMethods.CONTENT_URI, values);
+ } else {
+ provider.nonTransactionalInsert(
+ ContactMethods.CONTENT_URI, values);
+ }
+ }
+ }
+ }
+
+ if (extensionMap != null && extensionMap.size() > 0) {
+ ArrayList<ContentValues> contentValuesArray;
+ if (resolver != null) {
+ contentValuesArray = new ArrayList<ContentValues>();
+ } else {
+ contentValuesArray = null;
+ }
+ for (Entry<String, List<String>> entry : extensionMap.entrySet()) {
+ String key = entry.getKey();
+ List<String> list = entry.getValue();
+ for (String value : list) {
+ ContentValues values = new ContentValues();
+ values.put(Extensions.NAME, key);
+ values.put(Extensions.VALUE, value);
+ values.put(Extensions.PERSON_ID, personId);
+ if (resolver != null) {
+ contentValuesArray.add(values);
+ } else {
+ provider.nonTransactionalInsert(Extensions.CONTENT_URI, values);
+ }
+ }
+ }
+ if (resolver != null) {
+ resolver.bulkInsert(Extensions.CONTENT_URI,
+ contentValuesArray.toArray(new ContentValues[0]));
+ }
+ }
+
+ if (primaryPhoneId >= 0 || primaryOrganizationId >= 0 || primaryEmailId >= 0) {
+ ContentValues values = new ContentValues();
+ if (primaryPhoneId >= 0) {
+ values.put(People.PRIMARY_PHONE_ID, primaryPhoneId);
+ }
+ if (primaryOrganizationId >= 0) {
+ values.put(People.PRIMARY_ORGANIZATION_ID, primaryOrganizationId);
+ }
+ if (primaryEmailId >= 0) {
+ values.put(People.PRIMARY_EMAIL_ID, primaryEmailId);
+ }
+ if (resolver != null) {
+ resolver.update(personUri, values, null, null);
+ } else {
+ provider.nonTransactionalUpdate(personUri, values, null, null);
+ }
+ }
+ }
+
+ /**
+ * Push this object into database in the resolver.
+ */
+ public void pushIntoContentResolver(ContentResolver resolver) {
+ pushIntoContentProviderOrResolver(resolver, 0);
+ }
+
+ /**
+ * Push this object into AbstractSyncableContentProvider object.
+ */
+ public void pushIntoAbstractSyncableContentProvider(
+ AbstractSyncableContentProvider provider, long myContactsGroupId) {
+ boolean successful = false;
+ provider.beginTransaction();
+ try {
+ pushIntoContentProviderOrResolver(provider, myContactsGroupId);
+ successful = true;
+ } finally {
+ provider.endTransaction(successful);
+ }
+ }
+
+ public boolean isIgnorable() {
+ return TextUtils.isEmpty(name) &&
+ TextUtils.isEmpty(phoneticName) &&
+ (phoneList == null || phoneList.size() == 0) &&
+ (contactmethodList == null || contactmethodList.size() == 0);
}
}
diff --git a/core/java/android/syncml/pim/vcard/VCardComposer.java b/core/java/android/syncml/pim/vcard/VCardComposer.java
index 05e8f40..192736a 100644
--- a/core/java/android/syncml/pim/vcard/VCardComposer.java
+++ b/core/java/android/syncml/pim/vcard/VCardComposer.java
@@ -124,9 +124,9 @@
mResult.append("ORG:").append(struct.company).append(mNewline);
}
- if (!isNull(struct.notes)) {
+ if (struct.notes.size() > 0 && !isNull(struct.notes.get(0))) {
mResult.append("NOTE:").append(
- foldingString(struct.notes, vcardversion)).append(mNewline);
+ foldingString(struct.notes.get(0), vcardversion)).append(mNewline);
}
if (!isNull(struct.title)) {
@@ -190,7 +190,7 @@
*/
private void appendPhotoStr(byte[] bytes, String type, int version)
throws VCardException {
- String value, apptype, encodingStr;
+ String value, encodingStr;
try {
value = foldingString(new String(Base64.encodeBase64(bytes, true)),
version);
@@ -198,20 +198,23 @@
throw new VCardException(e.getMessage());
}
- if (isNull(type)) {
- type = "image/jpeg";
- }
- if (type.indexOf("jpeg") > 0) {
- apptype = "JPEG";
- } else if (type.indexOf("gif") > 0) {
- apptype = "GIF";
- } else if (type.indexOf("bmp") > 0) {
- apptype = "BMP";
+ if (isNull(type) || type.toUpperCase().indexOf("JPEG") >= 0) {
+ type = "JPEG";
+ } else if (type.toUpperCase().indexOf("GIF") >= 0) {
+ type = "GIF";
+ } else if (type.toUpperCase().indexOf("BMP") >= 0) {
+ type = "BMP";
} else {
- apptype = type.substring(type.indexOf("/")).toUpperCase();
+ // Handle the string like "image/tiff".
+ int indexOfSlash = type.indexOf("/");
+ if (indexOfSlash >= 0) {
+ type = type.substring(indexOfSlash + 1).toUpperCase();
+ } else {
+ type = type.toUpperCase();
+ }
}
- mResult.append("LOGO;TYPE=").append(apptype);
+ mResult.append("LOGO;TYPE=").append(type);
if (version == VERSION_VCARD21_INT) {
encodingStr = ";ENCODING=BASE64:";
value = value + mNewline;
@@ -281,7 +284,7 @@
private String getPhoneTypeStr(PhoneData phone) {
- int phoneType = Integer.parseInt(phone.type);
+ int phoneType = phone.type;
String typeStr, label;
if (phoneTypeMap.containsKey(phoneType)) {
@@ -308,7 +311,7 @@
String joinMark = version == VERSION_VCARD21_INT ? ";" : ",";
for (ContactStruct.ContactMethod contactMethod : contactMList) {
// same with v2.1 and v3.0
- switch (Integer.parseInt(contactMethod.kind)) {
+ switch (contactMethod.kind) {
case Contacts.KIND_EMAIL:
String mailType = "INTERNET";
if (!isNull(contactMethod.data)) {
diff --git a/core/java/android/syncml/pim/vcard/VCardDataBuilder.java b/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
new file mode 100644
index 0000000..a0513f1
--- /dev/null
+++ b/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2007 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.syncml.pim.vcard;
+
+import android.app.ProgressDialog;
+import android.content.AbstractSyncableContentProvider;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.IContentProvider;
+import android.os.Handler;
+import android.provider.Contacts;
+import android.syncml.pim.PropertyNode;
+import android.syncml.pim.VBuilder;
+import android.syncml.pim.VNode;
+import android.syncml.pim.VParser;
+import android.util.CharsetUtils;
+import android.util.Log;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.net.QuotedPrintableCodec;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * VBuilder for VCard. VCard may contain big photo images encoded by BASE64,
+ * If we store all VNode entries in memory like VDataBuilder.java,
+ * OutOfMemoryError may be thrown. Thus, this class push each VCard entry into
+ * ContentResolver immediately.
+ */
+public class VCardDataBuilder implements VBuilder {
+ static private String LOG_TAG = "VCardDataBuilder";
+
+ /**
+ * If there's no other information available, this class uses this charset for encoding
+ * byte arrays.
+ */
+ static public String DEFAULT_CHARSET = "UTF-8";
+
+ private class ProgressShower implements Runnable {
+ private ContactStruct mContact;
+
+ public ProgressShower(ContactStruct contact) {
+ mContact = contact;
+ }
+
+ public void run () {
+ mProgressDialog.setMessage(mProgressMessage + "\n" +
+ mContact.displayString());
+ }
+ }
+
+ /** type=VNode */
+ private VNode mCurrentVNode;
+ private PropertyNode mCurrentPropNode;
+ private String mCurrentParamType;
+
+ /**
+ * The charset using which VParser parses the text.
+ */
+ private String mSourceCharset;
+
+ /**
+ * The charset with which byte array is encoded to String.
+ */
+ private String mTargetCharset;
+ private boolean mStrictLineBreakParsing;
+ private ContentResolver mContentResolver;
+
+ // For letting VCardDataBuilder show the display name of VCard while handling it.
+ private Handler mHandler;
+ private ProgressDialog mProgressDialog;
+ private String mProgressMessage;
+ private Runnable mOnProgressRunnable;
+ private boolean mLastNameComesBeforeFirstName;
+
+ // Just for testing.
+ private long mTimeCreateContactStruct;
+ private long mTimePushIntoContentResolver;
+
+ // Ideally, this should be ContactsProvider but it seems Class loader cannot find it,
+ // even when it is subclass of ContactsProvider...
+ private AbstractSyncableContentProvider mProvider;
+ private long mMyContactsGroupId;
+
+ public VCardDataBuilder(ContentResolver resolver) {
+ mTargetCharset = DEFAULT_CHARSET;
+ mContentResolver = resolver;
+ }
+
+ /**
+ * Constructor which requires minimum requiredvariables.
+ *
+ * @param resolver insert each data into this ContentResolver
+ * @param progressDialog
+ * @param progressMessage
+ * @param handler if this importer works on the different thread than main one,
+ * set appropriate handler object. If not, it is ok to set this null.
+ */
+ public VCardDataBuilder(ContentResolver resolver,
+ ProgressDialog progressDialog,
+ String progressMessage,
+ Handler handler) {
+ this(resolver, progressDialog, progressMessage, handler,
+ null, null, false, false);
+ }
+
+ public VCardDataBuilder(ContentResolver resolver,
+ ProgressDialog progressDialog,
+ String progressMessage,
+ Handler handler,
+ String charset,
+ boolean strictLineBreakParsing,
+ boolean lastNameComesBeforeFirstName) {
+ this(resolver, progressDialog, progressMessage, handler,
+ null, charset, strictLineBreakParsing,
+ lastNameComesBeforeFirstName);
+ }
+
+ /**
+ * @hide
+ */
+ public VCardDataBuilder(ContentResolver resolver,
+ ProgressDialog progressDialog,
+ String progressMessage,
+ Handler handler,
+ String sourceCharset,
+ String targetCharset,
+ boolean strictLineBreakParsing,
+ boolean lastNameComesBeforeFirstName) {
+ if (sourceCharset != null) {
+ mSourceCharset = sourceCharset;
+ } else {
+ mSourceCharset = VParser.DEFAULT_CHARSET;
+ }
+ if (targetCharset != null) {
+ mTargetCharset = targetCharset;
+ } else {
+ mTargetCharset = DEFAULT_CHARSET;
+ }
+ mContentResolver = resolver;
+ mStrictLineBreakParsing = strictLineBreakParsing;
+ mHandler = handler;
+ mProgressDialog = progressDialog;
+ mProgressMessage = progressMessage;
+ mLastNameComesBeforeFirstName = lastNameComesBeforeFirstName;
+
+ tryGetOriginalProvider();
+ }
+
+ private void tryGetOriginalProvider() {
+ final ContentResolver resolver = mContentResolver;
+
+ if ((mMyContactsGroupId = Contacts.People.tryGetMyContactsGroupId(resolver)) == 0) {
+ Log.e(LOG_TAG, "Could not get group id of MyContact");
+ return;
+ }
+
+ IContentProvider iProviderForName = resolver.acquireProvider(Contacts.CONTENT_URI);
+ ContentProvider contentProvider =
+ ContentProvider.coerceToLocalContentProvider(iProviderForName);
+ if (contentProvider == null) {
+ Log.e(LOG_TAG, "Fail to get ContentProvider object.");
+ return;
+ }
+
+ if (!(contentProvider instanceof AbstractSyncableContentProvider)) {
+ Log.e(LOG_TAG,
+ "Acquired ContentProvider object is not AbstractSyncableContentProvider.");
+ return;
+ }
+
+ mProvider = (AbstractSyncableContentProvider)contentProvider;
+ }
+
+ public void setOnProgressRunnable(Runnable runnable) {
+ mOnProgressRunnable = runnable;
+ }
+
+ public void start() {
+ }
+
+ public void end() {
+ }
+
+ /**
+ * Assume that VCard is not nested. In other words, this code does not accept
+ */
+ public void startRecord(String type) {
+ if (mCurrentVNode != null) {
+ // This means startRecord() is called inside startRecord() - endRecord() block.
+ // TODO: should throw some Exception
+ Log.e(LOG_TAG, "Nested VCard code is not supported now.");
+ }
+ mCurrentVNode = new VNode();
+ mCurrentVNode.parseStatus = 1;
+ mCurrentVNode.VName = type;
+ }
+
+ public void endRecord() {
+ mCurrentVNode.parseStatus = 0;
+ long start = System.currentTimeMillis();
+ ContactStruct contact = ContactStruct.constructContactFromVNode(mCurrentVNode,
+ mLastNameComesBeforeFirstName ? ContactStruct.NAME_ORDER_TYPE_JAPANESE :
+ ContactStruct.NAME_ORDER_TYPE_ENGLISH);
+ mTimeCreateContactStruct += System.currentTimeMillis() - start;
+ if (!contact.isIgnorable()) {
+ if (mProgressDialog != null && mProgressMessage != null) {
+ if (mHandler != null) {
+ mHandler.post(new ProgressShower(contact));
+ } else {
+ mProgressDialog.setMessage(mProgressMessage + "\n" +
+ contact.displayString());
+ }
+ }
+ start = System.currentTimeMillis();
+ if (mProvider != null) {
+ contact.pushIntoAbstractSyncableContentProvider(
+ mProvider, mMyContactsGroupId);
+ } else {
+ contact.pushIntoContentResolver(mContentResolver);
+ }
+ mTimePushIntoContentResolver += System.currentTimeMillis() - start;
+ }
+ if (mOnProgressRunnable != null) {
+ mOnProgressRunnable.run();
+ }
+ mCurrentVNode = null;
+ }
+
+ public void startProperty() {
+ mCurrentPropNode = new PropertyNode();
+ }
+
+ public void endProperty() {
+ mCurrentVNode.propList.add(mCurrentPropNode);
+ mCurrentPropNode = null;
+ }
+
+ public void propertyName(String name) {
+ mCurrentPropNode.propName = name;
+ }
+
+ public void propertyGroup(String group) {
+ mCurrentPropNode.propGroupSet.add(group);
+ }
+
+ public void propertyParamType(String type) {
+ mCurrentParamType = type;
+ }
+
+ public void propertyParamValue(String value) {
+ if (mCurrentParamType == null ||
+ mCurrentParamType.equalsIgnoreCase("TYPE")) {
+ mCurrentPropNode.paramMap_TYPE.add(value);
+ } else {
+ mCurrentPropNode.paramMap.put(mCurrentParamType, value);
+ }
+
+ mCurrentParamType = null;
+ }
+
+ private String encodeString(String originalString, String targetCharset) {
+ if (mSourceCharset.equalsIgnoreCase(targetCharset)) {
+ return originalString;
+ }
+ Charset charset = Charset.forName(mSourceCharset);
+ ByteBuffer byteBuffer = charset.encode(originalString);
+ // byteBuffer.array() "may" return byte array which is larger than
+ // byteBuffer.remaining(). Here, we keep on the safe side.
+ byte[] bytes = new byte[byteBuffer.remaining()];
+ byteBuffer.get(bytes);
+ try {
+ return new String(bytes, targetCharset);
+ } catch (UnsupportedEncodingException e) {
+ Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
+ return new String(bytes);
+ }
+ }
+
+ private String handleOneValue(String value, String targetCharset, String encoding) {
+ if (encoding != null) {
+ if (encoding.equals("BASE64") || encoding.equals("B")) {
+ mCurrentPropNode.propValue_bytes =
+ Base64.decodeBase64(value.getBytes());
+ return value;
+ } else if (encoding.equals("QUOTED-PRINTABLE")) {
+ // "= " -> " ", "=\t" -> "\t".
+ // Previous code had done this replacement. Keep on the safe side.
+ StringBuilder builder = new StringBuilder();
+ int length = value.length();
+ for (int i = 0; i < length; i++) {
+ char ch = value.charAt(i);
+ if (ch == '=' && i < length - 1) {
+ char nextCh = value.charAt(i + 1);
+ if (nextCh == ' ' || nextCh == '\t') {
+
+ builder.append(nextCh);
+ i++;
+ continue;
+ }
+ }
+ builder.append(ch);
+ }
+ String quotedPrintable = builder.toString();
+
+ String[] lines;
+ if (mStrictLineBreakParsing) {
+ lines = quotedPrintable.split("\r\n");
+ } else {
+ builder = new StringBuilder();
+ length = quotedPrintable.length();
+ ArrayList<String> list = new ArrayList<String>();
+ for (int i = 0; i < length; i++) {
+ char ch = quotedPrintable.charAt(i);
+ if (ch == '\n') {
+ list.add(builder.toString());
+ builder = new StringBuilder();
+ } else if (ch == '\r') {
+ list.add(builder.toString());
+ builder = new StringBuilder();
+ if (i < length - 1) {
+ char nextCh = quotedPrintable.charAt(i + 1);
+ if (nextCh == '\n') {
+ i++;
+ }
+ }
+ } else {
+ builder.append(ch);
+ }
+ }
+ String finalLine = builder.toString();
+ if (finalLine.length() > 0) {
+ list.add(finalLine);
+ }
+ lines = list.toArray(new String[0]);
+ }
+
+ builder = new StringBuilder();
+ for (String line : lines) {
+ if (line.endsWith("=")) {
+ line = line.substring(0, line.length() - 1);
+ }
+ builder.append(line);
+ }
+ byte[] bytes;
+ try {
+ bytes = builder.toString().getBytes(mSourceCharset);
+ } catch (UnsupportedEncodingException e1) {
+ Log.e(LOG_TAG, "Failed to encode: charset=" + mSourceCharset);
+ bytes = builder.toString().getBytes();
+ }
+
+ try {
+ bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes);
+ } catch (DecoderException e) {
+ Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
+ return "";
+ }
+
+ try {
+ return new String(bytes, targetCharset);
+ } catch (UnsupportedEncodingException e) {
+ Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
+ return new String(bytes);
+ }
+ }
+ // Unknown encoding. Fall back to default.
+ }
+ return encodeString(value, targetCharset);
+ }
+
+ public void propertyValues(List<String> values) {
+ if (values == null || values.size() == 0) {
+ mCurrentPropNode.propValue_bytes = null;
+ mCurrentPropNode.propValue_vector.clear();
+ mCurrentPropNode.propValue_vector.add("");
+ mCurrentPropNode.propValue = "";
+ return;
+ }
+
+ ContentValues paramMap = mCurrentPropNode.paramMap;
+
+ String targetCharset = CharsetUtils.nameForDefaultVendor(paramMap.getAsString("CHARSET"));
+ String encoding = paramMap.getAsString("ENCODING");
+
+ if (targetCharset == null || targetCharset.length() == 0) {
+ targetCharset = mTargetCharset;
+ }
+
+ for (String value : values) {
+ mCurrentPropNode.propValue_vector.add(
+ handleOneValue(value, targetCharset, encoding));
+ }
+
+ mCurrentPropNode.propValue = listToString(mCurrentPropNode.propValue_vector);
+ }
+
+ public void showDebugInfo() {
+ Log.d(LOG_TAG, "time for creating ContactStruct: " + mTimeCreateContactStruct + " ms");
+ Log.d(LOG_TAG, "time for insert ContactStruct to database: " +
+ mTimePushIntoContentResolver + " ms");
+ }
+
+ private String listToString(List<String> list){
+ int size = list.size();
+ if (size > 1) {
+ StringBuilder builder = new StringBuilder();
+ int i = 0;
+ for (String type : list) {
+ builder.append(type);
+ if (i < size - 1) {
+ builder.append(";");
+ }
+ }
+ return builder.toString();
+ } else if (size == 1) {
+ return list.get(0);
+ } else {
+ return "";
+ }
+ }
+}
diff --git a/core/java/android/syncml/pim/vcard/VCardEntryCounter.java b/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
new file mode 100644
index 0000000..03cd1d9
--- /dev/null
+++ b/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.syncml.pim.vcard;
+
+import java.util.List;
+
+import android.syncml.pim.VBuilder;
+
+public class VCardEntryCounter implements VBuilder {
+ private int mCount;
+
+ public int getCount() {
+ return mCount;
+ }
+
+ public void start() {
+ }
+
+ public void end() {
+ }
+
+ public void startRecord(String type) {
+ }
+
+ public void endRecord() {
+ mCount++;
+ }
+
+ public void startProperty() {
+ }
+
+ public void endProperty() {
+ }
+
+ public void propertyGroup(String group) {
+ }
+
+ public void propertyName(String name) {
+ }
+
+ public void propertyParamType(String type) {
+ }
+
+ public void propertyParamValue(String value) {
+ }
+
+ public void propertyValues(List<String> values) {
+ }
+}
\ No newline at end of file
diff --git a/core/java/android/syncml/pim/vcard/VCardNestedException.java b/core/java/android/syncml/pim/vcard/VCardNestedException.java
new file mode 100644
index 0000000..def6f3b7
--- /dev/null
+++ b/core/java/android/syncml/pim/vcard/VCardNestedException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.syncml.pim.vcard;
+
+/**
+ * VCardException thrown when VCard is nested without VCardParser's being notified.
+ */
+public class VCardNestedException extends VCardException {
+ public VCardNestedException() {}
+ public VCardNestedException(String message) {
+ super(message);
+ }
+}
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V21.java b/core/java/android/syncml/pim/vcard/VCardParser_V21.java
index f853c5e..d865668 100644
--- a/core/java/android/syncml/pim/vcard/VCardParser_V21.java
+++ b/core/java/android/syncml/pim/vcard/VCardParser_V21.java
@@ -17,21 +17,26 @@
package android.syncml.pim.vcard;
import android.syncml.pim.VBuilder;
+import android.syncml.pim.VParser;
+import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-import java.util.regex.Pattern;
/**
- * This class is used to parse vcard. Please refer to vCard Specification 2.1
+ * This class is used to parse vcard. Please refer to vCard Specification 2.1.
*/
public class VCardParser_V21 {
-
+ private static final String LOG_TAG = "VCardParser_V21";
+
+ public static final String DEFAULT_CHARSET = VParser.DEFAULT_CHARSET;
+
/** Store the known-type */
private static final HashSet<String> sKnownTypeSet = new HashSet<String>(
Arrays.asList("DOM", "INTL", "POSTAL", "PARCEL", "HOME", "WORK",
@@ -42,19 +47,17 @@
"CGM", "WMF", "BMP", "MET", "PMB", "DIB", "PICT", "TIFF",
"PDF", "PS", "JPEG", "QTIME", "MPEG", "MPEG2", "AVI",
"WAVE", "AIFF", "PCM", "X509", "PGP"));
-
+
/** Store the known-value */
private static final HashSet<String> sKnownValueSet = new HashSet<String>(
Arrays.asList("INLINE", "URL", "CONTENT-ID", "CID"));
- /** Store the property name available in vCard 2.1 */
- // NICKNAME is not supported in vCard 2.1, but some vCard may contain.
+ /** Store the property names available in vCard 2.1 */
private static final HashSet<String> sAvailablePropertyNameV21 =
new HashSet<String>(Arrays.asList(
- "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
+ "BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
"VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
- "BDAY", "ROLE", "REV", "UID", "KEY", "MAILER",
- "NICKNAME"));
+ "BDAY", "ROLE", "REV", "UID", "KEY", "MAILER"));
// Though vCard 2.1 specification does not allow "B" encoding, some data may have it.
// We allow it for safety...
@@ -76,6 +79,30 @@
// Should not directly read a line from this. Use getLine() instead.
protected BufferedReader mReader;
+ private boolean mCanceled;
+
+ // In some cases, vCard is nested. Currently, we only consider the most interior vCard data.
+ // See v21_foma_1.vcf in test directory for more information.
+ private int mNestCount;
+
+ // In order to reduce warning message as much as possible, we hold the value which made Logger
+ // emit a warning message.
+ protected HashSet<String> mWarningValueMap = new HashSet<String>();
+
+ // Just for debugging
+ private long mTimeTotal;
+ private long mTimeStartRecord;
+ private long mTimeEndRecord;
+ private long mTimeStartProperty;
+ private long mTimeEndProperty;
+ private long mTimeParseItems;
+ private long mTimeParseItem1;
+ private long mTimeParseItem2;
+ private long mTimeParseItem3;
+ private long mTimeHandlePropertyValue1;
+ private long mTimeHandlePropertyValue2;
+ private long mTimeHandlePropertyValue3;
+
/**
* Create a new VCard parser.
*/
@@ -83,12 +110,35 @@
super();
}
+ public VCardParser_V21(VCardSourceDetector detector) {
+ super();
+ if (detector != null && detector.getType() == VCardSourceDetector.TYPE_FOMA) {
+ mNestCount = 1;
+ }
+ }
+
/**
* Parse the file at the given position
* vcard_file = [wsls] vcard [wsls]
*/
protected void parseVCardFile() throws IOException, VCardException {
- while (parseOneVCard()) {
+ boolean firstReading = true;
+ while (true) {
+ if (mCanceled) {
+ break;
+ }
+ if (!parseOneVCard(firstReading)) {
+ break;
+ }
+ firstReading = false;
+ }
+
+ if (mNestCount > 0) {
+ boolean useCache = true;
+ for (int i = 0; i < mNestCount; i++) {
+ readEndVCard(useCache, true);
+ useCache = false;
+ }
}
}
@@ -100,7 +150,13 @@
* @return true when the propertyName is a valid property name.
*/
protected boolean isValidPropertyName(String propertyName) {
- return sAvailablePropertyNameV21.contains(propertyName.toUpperCase());
+ if (!(sAvailablePropertyNameV21.contains(propertyName.toUpperCase()) ||
+ propertyName.startsWith("X-")) &&
+ !mWarningValueMap.contains(propertyName)) {
+ mWarningValueMap.add(propertyName);
+ Log.w(LOG_TAG, "Property name unsupported by vCard 2.1: " + propertyName);
+ }
+ return true;
}
/**
@@ -129,7 +185,7 @@
line = getLine();
if (line == null) {
throw new VCardException("Reached end of buffer.");
- } else if (line.trim().length() > 0) {
+ } else if (line.trim().length() > 0) {
return line;
}
}
@@ -140,12 +196,37 @@
* items *CRLF
* "END" [ws] ":" [ws] "VCARD"
*/
- private boolean parseOneVCard() throws IOException, VCardException {
- if (!readBeginVCard()) {
+ private boolean parseOneVCard(boolean firstReading) throws IOException, VCardException {
+ boolean allowGarbage = false;
+ if (firstReading) {
+ if (mNestCount > 0) {
+ for (int i = 0; i < mNestCount; i++) {
+ if (!readBeginVCard(allowGarbage)) {
+ return false;
+ }
+ allowGarbage = true;
+ }
+ }
+ }
+
+ if (!readBeginVCard(allowGarbage)) {
return false;
}
+ long start;
+ if (mBuilder != null) {
+ start = System.currentTimeMillis();
+ mBuilder.startRecord("VCARD");
+ mTimeStartRecord += System.currentTimeMillis() - start;
+ }
+ start = System.currentTimeMillis();
parseItems();
- readEndVCard();
+ mTimeParseItems += System.currentTimeMillis() - start;
+ readEndVCard(true, false);
+ if (mBuilder != null) {
+ start = System.currentTimeMillis();
+ mBuilder.endRecord();
+ mTimeEndRecord += System.currentTimeMillis() - start;
+ }
return true;
}
@@ -154,46 +235,102 @@
* @throws IOException
* @throws VCardException
*/
- protected boolean readBeginVCard() throws IOException, VCardException {
+ protected boolean readBeginVCard(boolean allowGarbage)
+ throws IOException, VCardException {
String line;
- while (true) {
- line = getLine();
- if (line == null) {
- return false;
- } else if (line.trim().length() > 0) {
- break;
+ do {
+ while (true) {
+ line = getLine();
+ if (line == null) {
+ return false;
+ } else if (line.trim().length() > 0) {
+ break;
+ }
}
- }
- String[] strArray = line.split(":", 2);
-
- // Though vCard specification does not allow lower cases,
- // some data may have them, so we allow it.
- if (!(strArray.length == 2 &&
- strArray[0].trim().equalsIgnoreCase("BEGIN") &&
- strArray[1].trim().equalsIgnoreCase("VCARD"))) {
- throw new VCardException("BEGIN:VCARD != \"" + line + "\"");
- }
-
- if (mBuilder != null) {
- mBuilder.startRecord("VCARD");
- }
+ String[] strArray = line.split(":", 2);
+ int length = strArray.length;
- return true;
+ // Though vCard 2.1/3.0 specification does not allow lower cases,
+ // some data may have them, so we allow it (Actually, previous code
+ // had explicitly allowed "BEGIN:vCard" though there's no example).
+ //
+ // TODO: ignore non vCard entry (e.g. vcalendar).
+ // XXX: Not sure, but according to VDataBuilder.java, vcalendar
+ // entry
+ // may be nested. Just seeking "END:SOMETHING" may not be enough.
+ // e.g.
+ // BEGIN:VCARD
+ // ... (Valid. Must parse this)
+ // END:VCARD
+ // BEGIN:VSOMETHING
+ // ... (Must ignore this)
+ // BEGIN:VSOMETHING2
+ // ... (Must ignore this)
+ // END:VSOMETHING2
+ // ... (Must ignore this!)
+ // END:VSOMETHING
+ // BEGIN:VCARD
+ // ... (Valid. Must parse this)
+ // END:VCARD
+ // INVALID_STRING (VCardException should be thrown)
+ if (length == 2 &&
+ strArray[0].trim().equalsIgnoreCase("BEGIN") &&
+ strArray[1].trim().equalsIgnoreCase("VCARD")) {
+ return true;
+ } else if (!allowGarbage) {
+ if (mNestCount > 0) {
+ mPreviousLine = line;
+ return false;
+ } else {
+ throw new VCardException(
+ "Expected String \"BEGIN:VCARD\" did not come "
+ + "(Instead, \"" + line + "\" came)");
+ }
+ }
+ } while(allowGarbage);
+
+ throw new VCardException("Reached where must not be reached.");
}
-
- protected void readEndVCard() throws VCardException {
- // Though vCard specification does not allow lower cases,
- // some data may have them, so we allow it.
- String[] strArray = mPreviousLine.split(":", 2);
- if (!(strArray.length == 2 &&
- strArray[0].trim().equalsIgnoreCase("END") &&
- strArray[1].trim().equalsIgnoreCase("VCARD"))) {
- throw new VCardException("END:VCARD != \"" + mPreviousLine + "\"");
- }
-
- if (mBuilder != null) {
- mBuilder.endRecord();
- }
+
+ /**
+ * The arguments useCache and allowGarbase are usually true and false accordingly when
+ * this function is called outside this function itself.
+ *
+ * @param useCache When true, line is obtained from mPreviousline. Otherwise, getLine()
+ * is used.
+ * @param allowGarbage When true, ignore non "END:VCARD" line.
+ * @throws IOException
+ * @throws VCardException
+ */
+ protected void readEndVCard(boolean useCache, boolean allowGarbage)
+ throws IOException, VCardException {
+ String line;
+ do {
+ if (useCache) {
+ // Though vCard specification does not allow lower cases,
+ // some data may have them, so we allow it.
+ line = mPreviousLine;
+ } else {
+ while (true) {
+ line = getLine();
+ if (line == null) {
+ throw new VCardException("Expected END:VCARD was not found.");
+ } else if (line.trim().length() > 0) {
+ break;
+ }
+ }
+ }
+
+ String[] strArray = line.split(":", 2);
+ if (strArray.length == 2 &&
+ strArray[0].trim().equalsIgnoreCase("END") &&
+ strArray[1].trim().equalsIgnoreCase("VCARD")) {
+ return;
+ } else if (!allowGarbage) {
+ throw new VCardException("END:VCARD != \"" + mPreviousLine + "\"");
+ }
+ useCache = false;
+ } while (allowGarbage);
}
/**
@@ -205,32 +342,33 @@
boolean ended = false;
if (mBuilder != null) {
+ long start = System.currentTimeMillis();
mBuilder.startProperty();
+ mTimeStartProperty += System.currentTimeMillis() - start;
}
-
- try {
- ended = parseItem();
- } finally {
- if (mBuilder != null) {
- mBuilder.endProperty();
- }
+ ended = parseItem();
+ if (mBuilder != null && !ended) {
+ long start = System.currentTimeMillis();
+ mBuilder.endProperty();
+ mTimeEndProperty += System.currentTimeMillis() - start;
}
while (!ended) {
// follow VCARD ,it wont reach endProperty
if (mBuilder != null) {
+ long start = System.currentTimeMillis();
mBuilder.startProperty();
+ mTimeStartProperty += System.currentTimeMillis() - start;
}
- try {
- ended = parseItem();
- } finally {
- if (mBuilder != null) {
- mBuilder.endProperty();
- }
+ ended = parseItem();
+ if (mBuilder != null && !ended) {
+ long start = System.currentTimeMillis();
+ mBuilder.endProperty();
+ mTimeEndProperty += System.currentTimeMillis() - start;
}
}
}
-
+
/**
* item = [groups "."] name [params] ":" value CRLF
* / [groups "."] "ADR" [params] ":" addressparts CRLF
@@ -241,50 +379,46 @@
protected boolean parseItem() throws IOException, VCardException {
mEncoding = sDefaultEncoding;
- // params = ";" [ws] paramlist
String line = getNonEmptyLine();
- String[] strArray = line.split(":", 2);
- if (strArray.length < 2) {
- throw new VCardException("Invalid line(\":\" does not exist): " + line);
- }
- String propertyValue = strArray[1];
- String[] groupNameParamsArray = strArray[0].split(";");
- String groupAndName = groupNameParamsArray[0].trim();
- String[] groupNameArray = groupAndName.split("\\.");
- int length = groupNameArray.length;
- String propertyName = groupNameArray[length - 1];
- if (mBuilder != null) {
- mBuilder.propertyName(propertyName);
- for (int i = 0; i < length - 1; i++) {
- mBuilder.propertyGroup(groupNameArray[i]);
- }
- }
- if (propertyName.equalsIgnoreCase("END")) {
- mPreviousLine = line;
+ long start = System.currentTimeMillis();
+
+ String[] propertyNameAndValue = separateLineAndHandleGroup(line);
+ if (propertyNameAndValue == null) {
return true;
}
-
- length = groupNameParamsArray.length;
- for (int i = 1; i < length; i++) {
- handleParams(groupNameParamsArray[i]);
+ if (propertyNameAndValue.length != 2) {
+ throw new VCardException("Invalid line \"" + line + "\"");
}
-
- if (isValidPropertyName(propertyName) ||
- propertyName.startsWith("X-")) {
- if (propertyName.equals("VERSION") &&
+ String propertyName = propertyNameAndValue[0].toUpperCase();
+ String propertyValue = propertyNameAndValue[1];
+
+ mTimeParseItem1 += System.currentTimeMillis() - start;
+
+ if (propertyName.equals("ADR") ||
+ propertyName.equals("ORG") ||
+ propertyName.equals("N")) {
+ start = System.currentTimeMillis();
+ handleMultiplePropertyValue(propertyName, propertyValue);
+ mTimeParseItem3 += System.currentTimeMillis() - start;
+ return false;
+ } else if (propertyName.equals("AGENT")) {
+ handleAgent(propertyValue);
+ return false;
+ } else if (isValidPropertyName(propertyName)) {
+ if (propertyName.equals("BEGIN")) {
+ if (propertyValue.equals("VCARD")) {
+ throw new VCardNestedException("This vCard has nested vCard data in it.");
+ } else {
+ throw new VCardException("Unknown BEGIN type: " + propertyValue);
+ }
+ } else if (propertyName.equals("VERSION") &&
!propertyValue.equals(getVersion())) {
throw new VCardVersionException("Incompatible version: " +
propertyValue + " != " + getVersion());
}
+ start = System.currentTimeMillis();
handlePropertyValue(propertyName, propertyValue);
- return false;
- } else if (propertyName.equals("ADR") ||
- propertyName.equals("ORG") ||
- propertyName.equals("N")) {
- handleMultiplePropertyValue(propertyName, propertyValue);
- return false;
- } else if (propertyName.equals("AGENT")) {
- handleAgent(propertyValue);
+ mTimeParseItem2 += System.currentTimeMillis() - start;
return false;
}
@@ -292,6 +426,87 @@
propertyName + "\"");
}
+ static private final int STATE_GROUP_OR_PROPNAME = 0;
+ static private final int STATE_PARAMS = 1;
+ // vCard 3.1 specification allows double-quoted param-value, while vCard 2.1 does not.
+ // This is just for safety.
+ static private final int STATE_PARAMS_IN_DQUOTE = 2;
+
+ protected String[] separateLineAndHandleGroup(String line) throws VCardException {
+ int length = line.length();
+ int state = STATE_GROUP_OR_PROPNAME;
+ int nameIndex = 0;
+
+ String[] propertyNameAndValue = new String[2];
+
+ for (int i = 0; i < length; i++) {
+ char ch = line.charAt(i);
+ switch (state) {
+ case STATE_GROUP_OR_PROPNAME:
+ if (ch == ':') {
+ String propertyName = line.substring(nameIndex, i);
+ if (propertyName.equalsIgnoreCase("END")) {
+ mPreviousLine = line;
+ return null;
+ }
+ if (mBuilder != null) {
+ mBuilder.propertyName(propertyName);
+ }
+ propertyNameAndValue[0] = propertyName;
+ if (i < length - 1) {
+ propertyNameAndValue[1] = line.substring(i + 1);
+ } else {
+ propertyNameAndValue[1] = "";
+ }
+ return propertyNameAndValue;
+ } else if (ch == '.') {
+ String groupName = line.substring(nameIndex, i);
+ if (mBuilder != null) {
+ mBuilder.propertyGroup(groupName);
+ }
+ nameIndex = i + 1;
+ } else if (ch == ';') {
+ String propertyName = line.substring(nameIndex, i);
+ if (propertyName.equalsIgnoreCase("END")) {
+ mPreviousLine = line;
+ return null;
+ }
+ if (mBuilder != null) {
+ mBuilder.propertyName(propertyName);
+ }
+ propertyNameAndValue[0] = propertyName;
+ nameIndex = i + 1;
+ state = STATE_PARAMS;
+ }
+ break;
+ case STATE_PARAMS:
+ if (ch == '"') {
+ state = STATE_PARAMS_IN_DQUOTE;
+ } else if (ch == ';') {
+ handleParams(line.substring(nameIndex, i));
+ nameIndex = i + 1;
+ } else if (ch == ':') {
+ handleParams(line.substring(nameIndex, i));
+ if (i < length - 1) {
+ propertyNameAndValue[1] = line.substring(i + 1);
+ } else {
+ propertyNameAndValue[1] = "";
+ }
+ return propertyNameAndValue;
+ }
+ break;
+ case STATE_PARAMS_IN_DQUOTE:
+ if (ch == '"') {
+ state = STATE_PARAMS;
+ }
+ break;
+ }
+ }
+
+ throw new VCardException("Invalid line: \"" + line + "\"");
+ }
+
+
/**
* params = ";" [ws] paramlist
* paramlist = paramlist [ws] ";" [ws] param
@@ -330,18 +545,19 @@
}
/**
- * typeval = knowntype / "X-" word
+ * ptypeval = knowntype / "X-" word
*/
- protected void handleType(String ptypeval) throws VCardException {
- if (sKnownTypeSet.contains(ptypeval.toUpperCase()) ||
- ptypeval.startsWith("X-")) {
- if (mBuilder != null) {
- mBuilder.propertyParamType("TYPE");
- mBuilder.propertyParamValue(ptypeval.toUpperCase());
- }
- } else {
- throw new VCardException("Unknown type: \"" + ptypeval + "\"");
- }
+ protected void handleType(String ptypeval) {
+ String upperTypeValue = ptypeval;
+ if (!(sKnownTypeSet.contains(upperTypeValue) || upperTypeValue.startsWith("X-")) &&
+ !mWarningValueMap.contains(ptypeval)) {
+ mWarningValueMap.add(ptypeval);
+ Log.w(LOG_TAG, "Type unsupported by vCard 2.1: " + ptypeval);
+ }
+ if (mBuilder != null) {
+ mBuilder.propertyParamType("TYPE");
+ mBuilder.propertyParamValue(upperTypeValue);
+ }
}
/**
@@ -427,31 +643,48 @@
protected void handlePropertyValue(
String propertyName, String propertyValue) throws
IOException, VCardException {
- if (mEncoding == null || mEncoding.equalsIgnoreCase("7BIT")
- || mEncoding.equalsIgnoreCase("8BIT")
- || mEncoding.toUpperCase().startsWith("X-")) {
- if (mBuilder != null) {
- ArrayList<String> v = new ArrayList<String>();
- v.add(maybeUnescapeText(propertyValue));
- mBuilder.propertyValues(v);
- }
- } else if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
+ if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
+ long start = System.currentTimeMillis();
String result = getQuotedPrintable(propertyValue);
if (mBuilder != null) {
ArrayList<String> v = new ArrayList<String>();
v.add(result);
mBuilder.propertyValues(v);
}
+ mTimeHandlePropertyValue2 += System.currentTimeMillis() - start;
} else if (mEncoding.equalsIgnoreCase("BASE64") ||
mEncoding.equalsIgnoreCase("B")) {
- String result = getBase64(propertyValue);
+ long start = System.currentTimeMillis();
+ // It is very rare, but some BASE64 data may be so big that
+ // OutOfMemoryError occurs. To ignore such cases, use try-catch.
+ try {
+ String result = getBase64(propertyValue);
+ if (mBuilder != null) {
+ ArrayList<String> v = new ArrayList<String>();
+ v.add(result);
+ mBuilder.propertyValues(v);
+ }
+ } catch (OutOfMemoryError error) {
+ Log.e(LOG_TAG, "OutOfMemoryError happened during parsing BASE64 data!");
+ if (mBuilder != null) {
+ mBuilder.propertyValues(null);
+ }
+ }
+ mTimeHandlePropertyValue3 += System.currentTimeMillis() - start;
+ } else {
+ if (!(mEncoding == null || mEncoding.equalsIgnoreCase("7BIT")
+ || mEncoding.equalsIgnoreCase("8BIT")
+ || mEncoding.toUpperCase().startsWith("X-"))) {
+ Log.w(LOG_TAG, "The encoding unsupported by vCard spec: \"" + mEncoding + "\".");
+ }
+
+ long start = System.currentTimeMillis();
if (mBuilder != null) {
ArrayList<String> v = new ArrayList<String>();
- v.add(result);
+ v.add(maybeUnescapeText(propertyValue));
mBuilder.propertyValues(v);
- }
- } else {
- throw new VCardException("Unknown encoding: \"" + mEncoding + "\"");
+ }
+ mTimeHandlePropertyValue1 += System.currentTimeMillis() - start;
}
}
@@ -546,57 +779,51 @@
if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
propertyValue = getQuotedPrintable(propertyValue);
}
-
- if (propertyValue.endsWith("\\")) {
- StringBuilder builder = new StringBuilder();
- // builder.append(propertyValue);
- builder.append(propertyValue.substring(0, propertyValue.length() - 1));
- try {
- String line;
- while (true) {
- line = getNonEmptyLine();
- // builder.append("\r\n");
- // builder.append(line);
- if (!line.endsWith("\\")) {
- builder.append(line);
- break;
- } else {
- builder.append(line.substring(0, line.length() - 1));
- }
- }
- } catch (IOException e) {
- throw new VCardException(
- "IOException is throw during reading propertyValue" + e);
- }
- // Now, propertyValue may contain "\r\n"
- propertyValue = builder.toString();
- }
if (mBuilder != null) {
- // In String#replaceAll() and Pattern class, "\\\\" means single slash.
-
- final String IMPOSSIBLE_STRING = "\0";
- // First replace two backslashes with impossible strings.
- propertyValue = propertyValue.replaceAll("\\\\\\\\", IMPOSSIBLE_STRING);
-
- // Now, split propertyValue with ; whose previous char is not back slash.
- Pattern pattern = Pattern.compile("(?<!\\\\);");
// TODO: limit should be set in accordance with propertyName?
- String[] strArray = pattern.split(propertyValue, -1);
- ArrayList<String> arrayList = new ArrayList<String>();
- for (String str : strArray) {
- // Replace impossible strings with original two backslashes
- arrayList.add(
- unescapeText(str.replaceAll(IMPOSSIBLE_STRING, "\\\\\\\\")));
+ StringBuilder builder = new StringBuilder();
+ ArrayList<String> list = new ArrayList<String>();
+ int length = propertyValue.length();
+ for (int i = 0; i < length; i++) {
+ char ch = propertyValue.charAt(i);
+ if (ch == '\\' && i < length - 1) {
+ char nextCh = propertyValue.charAt(i + 1);
+ String unescapedString = maybeUnescape(nextCh);
+ if (unescapedString != null) {
+ builder.append(unescapedString);
+ i++;
+ } else {
+ builder.append(ch);
+ }
+ } else if (ch == ';') {
+ list.add(builder.toString());
+ builder = new StringBuilder();
+ } else {
+ builder.append(ch);
+ }
}
- mBuilder.propertyValues(arrayList);
+ list.add(builder.toString());
+ mBuilder.propertyValues(list);
}
}
/**
* vCard 2.1 specifies AGENT allows one vcard entry. It is not encoded at all.
+ *
+ * item = ...
+ * / [groups "."] "AGENT"
+ * [params] ":" vcard CRLF
+ * vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF
+ * items *CRLF "END" [ws] ":" [ws] "VCARD"
+ *
*/
- protected void handleAgent(String propertyValue) throws IOException, VCardException {
+ protected void handleAgent(String propertyValue) throws VCardException {
+ throw new VCardException("AGENT Property is not supported.");
+ /* This is insufficient support. Also, AGENT Property is very rare.
+ Ignore it for now.
+ TODO: fix this.
+
String[] strArray = propertyValue.split(":", 2);
if (!(strArray.length == 2 ||
strArray[0].trim().equalsIgnoreCase("BEGIN") &&
@@ -605,6 +832,7 @@
}
parseItems();
readEndVCard();
+ */
}
/**
@@ -615,17 +843,18 @@
}
/**
- * Convert escaped text into unescaped text.
+ * Returns unescaped String if the character should be unescaped. Return null otherwise.
+ * e.g. In vCard 2.1, "\;" should be unescaped into ";" while "\x" should not be.
*/
- protected String unescapeText(String text) {
+ protected String maybeUnescape(char ch) {
// Original vCard 2.1 specification does not allow transformation
// "\:" -> ":", "\," -> ",", and "\\" -> "\", but previous implementation of
// this class allowed them, so keep it as is.
- // In String#replaceAll(), "\\\\" means single slash.
- return text.replaceAll("\\\\;", ";")
- .replaceAll("\\\\:", ":")
- .replaceAll("\\\\,", ",")
- .replaceAll("\\\\\\\\", "\\\\");
+ if (ch == '\\' || ch == ';' || ch == ':' || ch == ',') {
+ return String.valueOf(ch);
+ } else {
+ return null;
+ }
}
/**
@@ -656,12 +885,15 @@
*/
public boolean parse(InputStream is, String charset, VBuilder builder)
throws IOException, VCardException {
+ // TODO: make this count error entries instead of just throwing VCardException.
+
// TODO: If we really need to allow only CRLF as line break,
// we will have to develop our own BufferedReader().
- mReader = new BufferedReader(new InputStreamReader(is, charset));
+ mReader = new CustomBufferedReader(new InputStreamReader(is, charset));
mBuilder = builder;
+ long start = System.currentTimeMillis();
if (mBuilder != null) {
mBuilder.start();
}
@@ -669,9 +901,50 @@
if (mBuilder != null) {
mBuilder.end();
}
+ mTimeTotal += System.currentTimeMillis() - start;
+
return true;
}
+ public boolean parse(InputStream is, VBuilder builder) throws IOException, VCardException {
+ return parse(is, DEFAULT_CHARSET, builder);
+ }
+
+ /**
+ * Cancel parsing.
+ * Actual cancel is done after the end of the current one vcard entry parsing.
+ */
+ public void cancel() {
+ mCanceled = true;
+ }
+
+ /**
+ * It is very, very rare case, but there is a case where
+ * canceled may be already true outside this object.
+ * @hide
+ */
+ public void parse(InputStream is, String charset, VBuilder builder, boolean canceled)
+ throws IOException, VCardException {
+ mCanceled = canceled;
+ parse(is, charset, builder);
+ }
+
+ public void showDebugInfo() {
+ Log.d(LOG_TAG, "total parsing time: " + mTimeTotal + " ms");
+ if (mReader instanceof CustomBufferedReader) {
+ Log.d(LOG_TAG, "total readLine time: " +
+ ((CustomBufferedReader)mReader).getTotalmillisecond() + " ms");
+ }
+ Log.d(LOG_TAG, "mTimeStartRecord: " + mTimeStartRecord + " ms");
+ Log.d(LOG_TAG, "mTimeEndRecord: " + mTimeEndRecord + " ms");
+ Log.d(LOG_TAG, "mTimeParseItem1: " + mTimeParseItem1 + " ms");
+ Log.d(LOG_TAG, "mTimeParseItem2: " + mTimeParseItem2 + " ms");
+ Log.d(LOG_TAG, "mTimeParseItem3: " + mTimeParseItem3 + " ms");
+ Log.d(LOG_TAG, "mTimeHandlePropertyValue1: " + mTimeHandlePropertyValue1 + " ms");
+ Log.d(LOG_TAG, "mTimeHandlePropertyValue2: " + mTimeHandlePropertyValue2 + " ms");
+ Log.d(LOG_TAG, "mTimeHandlePropertyValue3: " + mTimeHandlePropertyValue3 + " ms");
+ }
+
private boolean isLetter(char ch) {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
return true;
@@ -679,3 +952,24 @@
return false;
}
}
+
+class CustomBufferedReader extends BufferedReader {
+ private long mTime;
+
+ public CustomBufferedReader(Reader in) {
+ super(in);
+ }
+
+ @Override
+ public String readLine() throws IOException {
+ long start = System.currentTimeMillis();
+ String ret = super.readLine();
+ long end = System.currentTimeMillis();
+ mTime += end - start;
+ return ret;
+ }
+
+ public long getTotalmillisecond() {
+ return mTime;
+ }
+}
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V30.java b/core/java/android/syncml/pim/vcard/VCardParser_V30.java
index 901bd49..e67525e 100644
--- a/core/java/android/syncml/pim/vcard/VCardParser_V30.java
+++ b/core/java/android/syncml/pim/vcard/VCardParser_V30.java
@@ -16,8 +16,9 @@
package android.syncml.pim.vcard;
+import android.util.Log;
+
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -26,9 +27,11 @@
* Please refer to vCard Specification 3.0 (http://tools.ietf.org/html/rfc2426)
*/
public class VCardParser_V30 extends VCardParser_V21 {
+ private static final String LOG_TAG = "VCardParser_V30";
+
private static final HashSet<String> acceptablePropsWithParam = new HashSet<String>(
Arrays.asList(
- "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
+ "BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
"VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
"BDAY", "ROLE", "REV", "UID", "KEY", "MAILER", // 2.1
"NAME", "PROFILE", "SOURCE", "NICKNAME", "CLASS",
@@ -51,8 +54,14 @@
@Override
protected boolean isValidPropertyName(String propertyName) {
- return acceptablePropsWithParam.contains(propertyName) ||
- acceptablePropsWithoutParam.contains(propertyName);
+ if (!(acceptablePropsWithParam.contains(propertyName) ||
+ acceptablePropsWithoutParam.contains(propertyName) ||
+ propertyName.startsWith("X-")) &&
+ !mWarningValueMap.contains(propertyName)) {
+ mWarningValueMap.add(propertyName);
+ Log.w(LOG_TAG, "Property name unsupported by vCard 3.0: " + propertyName);
+ }
+ return true;
}
@Override
@@ -100,7 +109,21 @@
}
} else if (line.charAt(0) == ' ' || line.charAt(0) == '\t') {
if (builder != null) {
- // TODO: Check whether MIME requires only one whitespace.
+ // See Section 5.8.1 of RFC 2425 (MIME-DIR document).
+ // Following is the excerpts from it.
+ //
+ // DESCRIPTION:This is a long description that exists on a long line.
+ //
+ // Can be represented as:
+ //
+ // DESCRIPTION:This is a long description
+ // that exists on a long line.
+ //
+ // It could also be represented as:
+ //
+ // DESCRIPTION:This is a long descrip
+ // tion that exists o
+ // n a long line.
builder.append(line.substring(1));
} else if (mPreviousLine != null) {
builder = new StringBuilder();
@@ -113,10 +136,13 @@
} else {
if (mPreviousLine == null) {
mPreviousLine = line;
+ if (builder != null) {
+ return builder.toString();
+ }
} else {
String ret = mPreviousLine;
mPreviousLine = line;
- return ret;
+ return ret;
}
}
}
@@ -130,15 +156,16 @@
* [group "."] "END" ":" "VCARD" 1*CRLF
*/
@Override
- protected boolean readBeginVCard() throws IOException, VCardException {
+ protected boolean readBeginVCard(boolean allowGarbage) throws IOException, VCardException {
// TODO: vCard 3.0 supports group.
- return super.readBeginVCard();
+ return super.readBeginVCard(allowGarbage);
}
@Override
- protected void readEndVCard() throws VCardException {
+ protected void readEndVCard(boolean useCache, boolean allowGarbage)
+ throws IOException, VCardException {
// TODO: vCard 3.0 supports group.
- super.readEndVCard();
+ super.readEndVCard(useCache, allowGarbage);
}
/**
@@ -214,23 +241,6 @@
throw new VCardException("AGENT in vCard 3.0 is not supported yet.");
}
- // vCard 3.0 supports "B" as BASE64 encoding.
- @Override
- protected void handlePropertyValue(
- String propertyName, String propertyValue) throws
- IOException, VCardException {
- if (mEncoding != null && mEncoding.equalsIgnoreCase("B")) {
- String result = getBase64(propertyValue);
- if (mBuilder != null) {
- ArrayList<String> v = new ArrayList<String>();
- v.add(result);
- mBuilder.propertyValues(v);
- }
- }
-
- super.handlePropertyValue(propertyName, propertyValue);
- }
-
/**
* vCard 3.0 does not require two CRLF at the last of BASE64 data.
* It only requires that data should be MIME-encoded.
@@ -259,27 +269,38 @@
}
/**
- * Return unescapeText(text).
- * In vCard 3.0, 8bit text is always encoded.
- */
- @Override
- protected String maybeUnescapeText(String text) {
- return unescapeText(text);
- }
-
- /**
* ESCAPED-CHAR = "\\" / "\;" / "\," / "\n" / "\N")
* ; \\ encodes \, \n or \N encodes newline
* ; \; encodes ;, \, encodes ,
- */
+ *
+ * Note: Apple escape ':' into '\:' while does not escape '\'
+ */
@Override
- protected String unescapeText(String text) {
- // In String#replaceAll(), "\\\\" means single slash.
- return text.replaceAll("\\\\;", ";")
- .replaceAll("\\\\:", ":")
- .replaceAll("\\\\,", ",")
- .replaceAll("\\\\n", "\r\n")
- .replaceAll("\\\\N", "\r\n")
- .replaceAll("\\\\\\\\", "\\\\");
+ protected String maybeUnescapeText(String text) {
+ StringBuilder builder = new StringBuilder();
+ int length = text.length();
+ for (int i = 0; i < length; i++) {
+ char ch = text.charAt(i);
+ if (ch == '\\' && i < length - 1) {
+ char next_ch = text.charAt(++i);
+ if (next_ch == 'n' || next_ch == 'N') {
+ builder.append("\r\n");
+ } else {
+ builder.append(next_ch);
+ }
+ } else {
+ builder.append(ch);
+ }
+ }
+ return builder.toString();
+ }
+
+ @Override
+ protected String maybeUnescape(char ch) {
+ if (ch == 'n' || ch == 'N') {
+ return "\r\n";
+ } else {
+ return String.valueOf(ch);
+ }
}
}
diff --git a/core/java/android/syncml/pim/vcard/VCardSourceDetector.java b/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
new file mode 100644
index 0000000..8c48391
--- /dev/null
+++ b/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.syncml.pim.vcard;
+
+import android.syncml.pim.VBuilder;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Class which tries to detects the source of the vCard from its properties.
+ * Currently this implementation is very premature.
+ * @hide
+ */
+public class VCardSourceDetector implements VBuilder {
+ // Should only be used in package.
+ static final int TYPE_UNKNOWN = 0;
+ static final int TYPE_APPLE = 1;
+ static final int TYPE_JAPANESE_MOBILE_PHONE = 2; // Used in Japanese mobile phones.
+ static final int TYPE_FOMA = 3; // Used in some Japanese FOMA mobile phones.
+ static final int TYPE_WINDOWS_MOBILE_JP = 4;
+ // TODO: Excel, etc.
+
+ private static Set<String> APPLE_SIGNS = new HashSet<String>(Arrays.asList(
+ "X-PHONETIC-FIRST-NAME", "X-PHONETIC-MIDDLE-NAME", "X-PHONETIC-LAST-NAME",
+ "X-ABADR", "X-ABUID"));
+
+ private static Set<String> JAPANESE_MOBILE_PHONE_SIGNS = new HashSet<String>(Arrays.asList(
+ "X-GNO", "X-GN", "X-REDUCTION"));
+
+ private static Set<String> WINDOWS_MOBILE_PHONE_SIGNS = new HashSet<String>(Arrays.asList(
+ "X-MICROSOFT-ASST_TEL", "X-MICROSOFT-ASSISTANT", "X-MICROSOFT-OFFICELOC"));
+
+ // Note: these signes appears before the signs of the other type (e.g. "X-GN").
+ // In other words, Japanese FOMA mobile phones are detected as FOMA, not JAPANESE_MOBILE_PHONES.
+ private static Set<String> FOMA_SIGNS = new HashSet<String>(Arrays.asList(
+ "X-SD-VERN", "X-SD-FORMAT_VER", "X-SD-CATEGORIES", "X-SD-CLASS", "X-SD-DCREATED",
+ "X-SD-DESCRIPTION"));
+ private static String TYPE_FOMA_CHARSET_SIGN = "X-SD-CHAR_CODE";
+
+ private int mType = TYPE_UNKNOWN;
+ // Some mobile phones (like FOMA) tells us the charset of the data.
+ private boolean mNeedParseSpecifiedCharset;
+ private String mSpecifiedCharset;
+
+ public void start() {
+ }
+
+ public void end() {
+ }
+
+ public void startRecord(String type) {
+ }
+
+ public void startProperty() {
+ mNeedParseSpecifiedCharset = false;
+ }
+
+ public void endProperty() {
+ }
+
+ public void endRecord() {
+ }
+
+ public void propertyGroup(String group) {
+ }
+
+ public void propertyName(String name) {
+ if (name.equalsIgnoreCase(TYPE_FOMA_CHARSET_SIGN)) {
+ mType = TYPE_FOMA;
+ mNeedParseSpecifiedCharset = true;
+ return;
+ }
+ if (mType != TYPE_UNKNOWN) {
+ return;
+ }
+ if (WINDOWS_MOBILE_PHONE_SIGNS.contains(name)) {
+ mType = TYPE_WINDOWS_MOBILE_JP;
+ } else if (FOMA_SIGNS.contains(name)) {
+ mType = TYPE_FOMA;
+ } else if (JAPANESE_MOBILE_PHONE_SIGNS.contains(name)) {
+ mType = TYPE_JAPANESE_MOBILE_PHONE;
+ } else if (APPLE_SIGNS.contains(name)) {
+ mType = TYPE_APPLE;
+ }
+ }
+
+ public void propertyParamType(String type) {
+ }
+
+ public void propertyParamValue(String value) {
+ }
+
+ public void propertyValues(List<String> values) {
+ if (mNeedParseSpecifiedCharset && values.size() > 0) {
+ mSpecifiedCharset = values.get(0);
+ }
+ }
+
+ int getType() {
+ return mType;
+ }
+
+ /**
+ * Return charset String guessed from the source's properties.
+ * This method must be called after parsing target file(s).
+ * @return Charset String. Null is returned if guessing the source fails.
+ */
+ public String getEstimatedCharset() {
+ if (mSpecifiedCharset != null) {
+ return mSpecifiedCharset;
+ }
+ switch (mType) {
+ case TYPE_WINDOWS_MOBILE_JP:
+ case TYPE_FOMA:
+ case TYPE_JAPANESE_MOBILE_PHONE:
+ return "SHIFT_JIS";
+ case TYPE_APPLE:
+ return "UTF-8";
+ default:
+ return null;
+ }
+ }
+}
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 0dc96c3..3156d8b 100644
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -242,64 +242,48 @@
/**
* Returns a {@link java.text.DateFormat} object that can format the time according
- * to the current user preference.
+ * to the current locale.
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the time.
*/
public static final java.text.DateFormat getTimeFormat(Context context) {
- boolean b24 = is24HourFormat(context);
- int res;
-
- if (b24) {
- res = R.string.twenty_four_hour_time_format;
- } else {
- res = R.string.twelve_hour_time_format;
- }
-
- return new java.text.SimpleDateFormat(context.getString(res));
+ return java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
}
/**
- * Returns a {@link java.text.DateFormat} object that can format the date according
- * to the current user preference.
+ * Returns a {@link java.text.DateFormat} object that can format the date
+ * in short form (such as 12/31/1999) according
+ * to the current locale.
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the date.
*/
public static final java.text.DateFormat getDateFormat(Context context) {
- String value = getDateFormatString(context);
+ /*
+ * We use a resource string here instead of just DateFormat.SHORT
+ * so that we get a four-digit year instead a two-digit year.
+ */
+ String value = context.getString(R.string.numeric_date_format);
return new java.text.SimpleDateFormat(value);
}
/**
* Returns a {@link java.text.DateFormat} object that can format the date
- * in long form (such as December 31, 1999) based on user preference.
+ * in long form (such as December 31, 1999) for the current locale.
* @param context the application context
* @return the {@link java.text.DateFormat} object that formats the date in long form.
*/
public static final java.text.DateFormat getLongDateFormat(Context context) {
- String value = getDateFormatString(context);
- if (value.indexOf('M') < value.indexOf('d')) {
- value = context.getString(R.string.full_date_month_first);
- } else {
- value = context.getString(R.string.full_date_day_first);
- }
- return new java.text.SimpleDateFormat(value);
+ return java.text.DateFormat.getDateInstance(java.text.DateFormat.LONG);
}
/**
* Returns a {@link java.text.DateFormat} object that can format the date
- * in medium form (such as Dec. 31, 1999) based on user preference.
+ * in medium form (such as Dec. 31, 1999) for the current locale.
* @param context the application context
* @return the {@link java.text.DateFormat} object that formats the date in long form.
*/
public static final java.text.DateFormat getMediumDateFormat(Context context) {
- String value = getDateFormatString(context);
- if (value.indexOf('M') < value.indexOf('d')) {
- value = context.getString(R.string.medium_date_month_first);
- } else {
- value = context.getString(R.string.medium_date_day_first);
- }
- return new java.text.SimpleDateFormat(value);
+ return java.text.DateFormat.getDateInstance(java.text.DateFormat.MEDIUM);
}
/**
@@ -338,6 +322,12 @@
}
private static String getDateFormatString(Context context) {
+ java.text.DateFormat df;
+ df = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT);
+ if (df instanceof SimpleDateFormat) {
+ return ((SimpleDateFormat) df).toPattern();
+ }
+
String value = Settings.System.getString(context.getContentResolver(),
Settings.System.DATE_FORMAT);
if (value == null || value.length() < 6) {
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 8a7cdd9..9073d82 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -62,15 +62,6 @@
com.android.internal.R.string.day_of_week_short_friday,
com.android.internal.R.string.day_of_week_short_saturday,
};
- private static final int[] sDaysShorter = new int[] {
- com.android.internal.R.string.day_of_week_shorter_sunday,
- com.android.internal.R.string.day_of_week_shorter_monday,
- com.android.internal.R.string.day_of_week_shorter_tuesday,
- com.android.internal.R.string.day_of_week_shorter_wednesday,
- com.android.internal.R.string.day_of_week_shorter_thursday,
- com.android.internal.R.string.day_of_week_shorter_friday,
- com.android.internal.R.string.day_of_week_shorter_saturday,
- };
private static final int[] sDaysShortest = new int[] {
com.android.internal.R.string.day_of_week_shortest_sunday,
com.android.internal.R.string.day_of_week_shortest_monday,
@@ -80,6 +71,20 @@
com.android.internal.R.string.day_of_week_shortest_friday,
com.android.internal.R.string.day_of_week_shortest_saturday,
};
+ private static final int[] sMonthsStandaloneLong = new int [] {
+ com.android.internal.R.string.month_long_standalone_january,
+ com.android.internal.R.string.month_long_standalone_february,
+ com.android.internal.R.string.month_long_standalone_march,
+ com.android.internal.R.string.month_long_standalone_april,
+ com.android.internal.R.string.month_long_standalone_may,
+ com.android.internal.R.string.month_long_standalone_june,
+ com.android.internal.R.string.month_long_standalone_july,
+ com.android.internal.R.string.month_long_standalone_august,
+ com.android.internal.R.string.month_long_standalone_september,
+ com.android.internal.R.string.month_long_standalone_october,
+ com.android.internal.R.string.month_long_standalone_november,
+ com.android.internal.R.string.month_long_standalone_december,
+ };
private static final int[] sMonthsLong = new int [] {
com.android.internal.R.string.month_long_january,
com.android.internal.R.string.month_long_february,
@@ -127,7 +132,7 @@
com.android.internal.R.string.pm,
};
private static Configuration sLastConfig;
- private static String sStatusTimeFormat;
+ private static java.text.DateFormat sStatusTimeFormat;
private static String sElapsedFormatMMSS;
private static String sElapsedFormatHMMSS;
@@ -255,18 +260,15 @@
* For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}.
* @more
* <p>e.g. "Su" or "Jan"
- * <p>In some languages, the results returned for LENGTH_SHORT may be the same as
- * return for {@link #LENGTH_MEDIUM}.
+ * <p>In most languages, the results returned for LENGTH_SHORT will be the same as
+ * the results returned for {@link #LENGTH_MEDIUM}.
*/
public static final int LENGTH_SHORT = 30;
/**
* Request an even shorter abbreviated version of the name.
- * For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}.
- * @more
- * <p>e.g. "M", "Tu", "Th" or "J"
- * <p>In some languages, the results returned for LENGTH_SHORTEST may be the same as
- * return for {@link #LENGTH_SHORTER}.
+ * Do not use this. Currently this will always return the same result
+ * as {@link #LENGTH_SHORT}.
*/
public static final int LENGTH_SHORTER = 40;
@@ -275,8 +277,8 @@
* For use with the 'abbrev' parameter of {@link #getDayOfWeekString} and {@link #getMonthString}.
* @more
* <p>e.g. "S", "T", "T" or "J"
- * <p>In some languages, the results returned for LENGTH_SHORTEST may be the same as
- * return for {@link #LENGTH_SHORTER}.
+ * <p>In some languages, the results returned for LENGTH_SHORTEST will be the same as
+ * the results returned for {@link #LENGTH_SHORT}.
*/
public static final int LENGTH_SHORTEST = 50;
@@ -284,9 +286,12 @@
* Return a string for the day of the week.
* @param dayOfWeek One of {@link Calendar#SUNDAY Calendar.SUNDAY},
* {@link Calendar#MONDAY Calendar.MONDAY}, etc.
- * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_SHORT}, {@link #LENGTH_SHORTER}
- * or {@link #LENGTH_SHORTEST}. For forward compatibility, anything else
- * will return the same as {#LENGTH_MEDIUM}.
+ * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_SHORT},
+ * {@link #LENGTH_MEDIUM}, or {@link #LENGTH_SHORTEST}.
+ * Note that in most languages, {@link #LENGTH_SHORT}
+ * will return the same as {@link #LENGTH_MEDIUM}.
+ * Undefined lengths will return {@link #LENGTH_MEDIUM}
+ * but may return something different in the future.
* @throws IndexOutOfBoundsException if the dayOfWeek is out of bounds.
*/
public static String getDayOfWeekString(int dayOfWeek, int abbrev) {
@@ -295,7 +300,7 @@
case LENGTH_LONG: list = sDaysLong; break;
case LENGTH_MEDIUM: list = sDaysMedium; break;
case LENGTH_SHORT: list = sDaysShort; break;
- case LENGTH_SHORTER: list = sDaysShorter; break;
+ case LENGTH_SHORTER: list = sDaysShort; break;
case LENGTH_SHORTEST: list = sDaysShortest; break;
default: list = sDaysMedium; break;
}
@@ -316,13 +321,14 @@
}
/**
- * Return a localized string for the day of the week.
+ * Return a localized string for the month of the year.
* @param month One of {@link Calendar#JANUARY Calendar.JANUARY},
* {@link Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
- * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_SHORT}, {@link #LENGTH_SHORTER}
- * or {@link #LENGTH_SHORTEST}. For forward compatibility, anything else
- * will return the same as {#LENGTH_MEDIUM}.
- * @return Localized day of the week.
+ * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_MEDIUM},
+ * or {@link #LENGTH_SHORTEST}.
+ * Undefined lengths will return {@link #LENGTH_MEDIUM}
+ * but may return something different in the future.
+ * @return Localized month of the year.
*/
public static String getMonthString(int month, int abbrev) {
// Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
@@ -344,6 +350,40 @@
}
/**
+ * Return a localized string for the month of the year, for
+ * contexts where the month is not formatted together with
+ * a day of the month.
+ *
+ * @param month One of {@link Calendar#JANUARY Calendar.JANUARY},
+ * {@link Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
+ * @param abbrev One of {@link #LENGTH_LONG}, {@link #LENGTH_MEDIUM},
+ * or {@link #LENGTH_SHORTEST}.
+ * Undefined lengths will return {@link #LENGTH_MEDIUM}
+ * but may return something different in the future.
+ * @return Localized month of the year.
+ * @hide Pending API council approval
+ */
+ public static String getStandaloneMonthString(int month, int abbrev) {
+ // Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER.
+ // This is a shortcut to not spam the translators with too many variations
+ // of the same string. If we find that in a language the distinction
+ // is necessary, we can can add more without changing this API.
+ int[] list;
+ switch (abbrev) {
+ case LENGTH_LONG: list = sMonthsStandaloneLong;
+ break;
+ case LENGTH_MEDIUM: list = sMonthsMedium; break;
+ case LENGTH_SHORT: list = sMonthsMedium; break;
+ case LENGTH_SHORTER: list = sMonthsMedium; break;
+ case LENGTH_SHORTEST: list = sMonthsShortest; break;
+ default: list = sMonthsMedium; break;
+ }
+
+ Resources r = Resources.getSystem();
+ return r.getString(list[month - Calendar.JANUARY]);
+ }
+
+ /**
* Returns a string describing the elapsed time since startTime.
* @param startTime some time in the past.
* @return a String object containing the elapsed time.
@@ -572,7 +612,7 @@
Configuration cfg = r.getConfiguration();
if (sLastConfig == null || !sLastConfig.equals(cfg)) {
sLastConfig = cfg;
- sStatusTimeFormat = r.getString(com.android.internal.R.string.status_bar_time_format);
+ sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
}
@@ -586,7 +626,7 @@
*/
public static final CharSequence timeString(long millis) {
initFormatStrings();
- return DateFormat.format(sStatusTimeFormat, millis);
+ return sStatusTimeFormat.format(millis);
}
/**
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index daa99c2..8eae111 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -135,6 +135,7 @@
private static Locale sLocale;
private static String[] sShortMonths;
private static String[] sLongMonths;
+ private static String[] sLongStandaloneMonths;
private static String[] sShortWeekdays;
private static String[] sLongWeekdays;
private static String sTimeOnlyFormat;
@@ -321,6 +322,20 @@
r.getString(com.android.internal.R.string.month_long_november),
r.getString(com.android.internal.R.string.month_long_december),
};
+ sLongStandaloneMonths = new String[] {
+ r.getString(com.android.internal.R.string.month_long_standalone_january),
+ r.getString(com.android.internal.R.string.month_long_standalone_february),
+ r.getString(com.android.internal.R.string.month_long_standalone_march),
+ r.getString(com.android.internal.R.string.month_long_standalone_april),
+ r.getString(com.android.internal.R.string.month_long_standalone_may),
+ r.getString(com.android.internal.R.string.month_long_standalone_june),
+ r.getString(com.android.internal.R.string.month_long_standalone_july),
+ r.getString(com.android.internal.R.string.month_long_standalone_august),
+ r.getString(com.android.internal.R.string.month_long_standalone_september),
+ r.getString(com.android.internal.R.string.month_long_standalone_october),
+ r.getString(com.android.internal.R.string.month_long_standalone_november),
+ r.getString(com.android.internal.R.string.month_long_standalone_december),
+ };
sShortWeekdays = new String[] {
r.getString(com.android.internal.R.string.day_of_week_medium_sunday),
r.getString(com.android.internal.R.string.day_of_week_medium_monday),
@@ -438,6 +453,7 @@
*
* @param s the string to parse
* @return true if the resulting time value is in UTC time
+ * @throws android.util.TimeFormatException if s cannot be parsed.
*/
public boolean parse3339(String s) {
if (nativeParse3339(s)) {
diff --git a/core/java/android/util/CharsetUtils.java b/core/java/android/util/CharsetUtils.java
index 7553029..9d91aca 100644
--- a/core/java/android/util/CharsetUtils.java
+++ b/core/java/android/util/CharsetUtils.java
@@ -142,20 +142,25 @@
/**
* Returns whether the given character set name indicates the Shift-JIS
- * encoding.
+ * encoding. Returns false if the name is null.
*
* @param charsetName the character set name
* @return {@code true} if the name corresponds to Shift-JIS or
* {@code false} if not
*/
private static boolean isShiftJis(String charsetName) {
- if (charsetName.length() != 9) {
- // Bail quickly if the length doesn't match.
+ // Bail quickly if the length doesn't match.
+ if (charsetName == null) {
+ return false;
+ }
+ int length = charsetName.length();
+ if (length != 4 && length != 9) {
return false;
}
return charsetName.equalsIgnoreCase("shift_jis")
- || charsetName.equalsIgnoreCase("shift-jis");
+ || charsetName.equalsIgnoreCase("shift-jis")
+ || charsetName.equalsIgnoreCase("sjis");
}
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 40b03c8..3d023f7 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -326,8 +326,9 @@
mFormat = mRequestedFormat;
mType = mRequestedType;
- mLayout.x = mLeft;
- mLayout.y = mTop;
+ // Scaling window's layout here beause mLayout is not used elsewhere.
+ mLayout.x = (int) (mLeft * mAppScale);
+ mLayout.y = (int) (mTop * mAppScale);
mLayout.width = (int) (getWidth() * mAppScale);
mLayout.height = (int) (getHeight() * mAppScale);
mLayout.format = mRequestedFormat;
@@ -380,7 +381,7 @@
synchronized (mCallbacks) {
callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
mCallbacks.toArray(callbacks);
- }
+ }
if (visibleChanged) {
mIsCreating = true;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 335b43c..1f72eea 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,6 +16,9 @@
package android.view;
+import com.android.internal.R;
+import com.android.internal.view.menu.MenuBuilder;
+
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -25,12 +28,12 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader;
-import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
@@ -42,29 +45,30 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.AttributeSet;
+import android.util.Config;
import android.util.EventLog;
import android.util.Log;
-import android.util.SparseArray;
-import android.util.Poolable;
import android.util.Pool;
-import android.util.Pools;
+import android.util.Poolable;
import android.util.PoolableManager;
+import android.util.Pools;
+import android.util.SparseArray;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityEventSource;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.EditorInfo;
import android.widget.ScrollBarDrawable;
-import com.android.internal.R;
-import com.android.internal.view.menu.MenuBuilder;
-
+import java.lang.ref.SoftReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.WeakHashMap;
-import java.lang.ref.SoftReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
/**
* <p>
@@ -552,7 +556,7 @@
*
* @see android.view.ViewGroup
*/
-public class View implements Drawable.Callback, KeyEvent.Callback {
+public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
private static final boolean DBG = false;
/**
@@ -850,26 +854,16 @@
public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000;
/**
- * View flag indicating whether this view was invalidated (fully or partially.)
- *
- * @hide
+ * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
+ * should add all focusable Views regardless if they are focusable in touch mode.
*/
- static final int DIRTY = 0x20000000;
+ public static final int FOCUSABLES_ALL = 0x00000000;
/**
- * View flag indicating whether this view was invalidated by an opaque
- * invalidate request.
- *
- * @hide
+ * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
+ * should add only Views focusable in touch mode.
*/
- static final int DIRTY_OPAQUE = 0x40000000;
-
- /**
- * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}.
- *
- * @hide
- */
- static final int DIRTY_MASK = 0x60000000;
+ public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
/**
* Use with {@link #focusSearch}. Move focus to the previous selectable
@@ -1427,6 +1421,49 @@
static final int SCROLL_CONTAINER_ADDED = 0x00100000;
/**
+ * View flag indicating whether this view was invalidated (fully or partially.)
+ *
+ * @hide
+ */
+ static final int DIRTY = 0x00200000;
+
+ /**
+ * View flag indicating whether this view was invalidated by an opaque
+ * invalidate request.
+ *
+ * @hide
+ */
+ static final int DIRTY_OPAQUE = 0x00400000;
+
+ /**
+ * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}.
+ *
+ * @hide
+ */
+ static final int DIRTY_MASK = 0x00600000;
+
+ /**
+ * Indicates whether the background is opaque.
+ *
+ * @hide
+ */
+ static final int OPAQUE_BACKGROUND = 0x00800000;
+
+ /**
+ * Indicates whether the scrollbars are opaque.
+ *
+ * @hide
+ */
+ static final int OPAQUE_SCROLLBARS = 0x01000000;
+
+ /**
+ * Indicates whether the view is opaque.
+ *
+ * @hide
+ */
+ static final int OPAQUE_MASK = 0x01800000;
+
+ /**
* The parent this view is attached to.
* {@hide}
*
@@ -1442,7 +1479,18 @@
/**
* {@hide}
*/
- @ViewDebug.ExportedProperty
+ @ViewDebug.ExportedProperty(flagMapping = {
+ @ViewDebug.FlagToString(mask = FORCE_LAYOUT, equals = FORCE_LAYOUT,
+ name = "FORCE_LAYOUT"),
+ @ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED,
+ name = "LAYOUT_REQUIRED"),
+ @ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID,
+ name = "DRAWING_CACHE_INVALID", outputIf = false),
+ @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true),
+ @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false),
+ @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
+ @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY, name = "DIRTY")
+ })
int mPrivateFlags;
/**
@@ -1539,6 +1587,11 @@
protected int mPaddingBottom;
/**
+ * Briefly describes the view and is primarily used for accessibility support.
+ */
+ private CharSequence mContentDescription;
+
+ /**
* Cache the paddingRight set by the user to append to the scrollbar's size.
*/
@ViewDebug.ExportedProperty
@@ -1689,7 +1742,7 @@
public View(Context context) {
mContext = context;
mResources = context != null ? context.getResources() : null;
- mViewFlags = SOUND_EFFECTS_ENABLED|HAPTIC_FEEDBACK_ENABLED;
+ mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
++sInstanceCount;
}
@@ -1846,6 +1899,9 @@
viewFlagMasks |= DRAWING_CACHE_QUALITY_MASK;
}
break;
+ case com.android.internal.R.styleable.View_contentDescription:
+ mContentDescription = a.getString(attr);
+ break;
case com.android.internal.R.styleable.View_soundEffectsEnabled:
if (!a.getBoolean(attr, true)) {
viewFlagValues &= ~SOUND_EFFECTS_ENABLED;
@@ -1978,7 +2034,9 @@
if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
setScrollContainer(true);
}
-
+
+ computeOpaqueFlags();
+
a.recycle();
}
@@ -2243,6 +2301,8 @@
* otherwise is returned.
*/
public boolean performClick() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+
if (mOnClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mOnClickListener.onClick(this);
@@ -2260,6 +2320,8 @@
* otherwise is returned.
*/
public boolean performLongClick() {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+
boolean handled = false;
if (mOnLongClickListener != null) {
handled = mOnLongClickListener.onLongClick(View.this);
@@ -2480,6 +2542,10 @@
* from (in addition to direction). Will be <code>null</code> otherwise.
*/
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+ if (gainFocus) {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ }
+
InputMethodManager imm = InputMethodManager.peekInstance();
if (!gainFocus) {
if (isPressed()) {
@@ -2502,6 +2568,79 @@
}
/**
+ * {@inheritDoc}
+ */
+ public void sendAccessibilityEvent(int eventType) {
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
+ event.setClassName(getClass().getName());
+ event.setPackageName(getContext().getPackageName());
+ event.setEnabled(isEnabled());
+ event.setContentDescription(mContentDescription);
+
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && mAttachInfo != null) {
+ ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
+ getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD, FOCUSABLES_ALL);
+ event.setItemCount(focusablesTempList.size());
+ event.setCurrentItemIndex(focusablesTempList.indexOf(this));
+ focusablesTempList.clear();
+ }
+
+ dispatchPopulateAccessibilityEvent(event);
+
+ AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
+ }
+
+ /**
+ * Dispatches an {@link AccessibilityEvent} to the {@link View} children
+ * to be populated.
+ *
+ * @param event The event.
+ *
+ * @return True if the event population was completed.
+ */
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ return false;
+ }
+
+ /**
+ * Gets the {@link View} description. It briefly describes the view and is
+ * primarily used for accessibility support. Set this property to enable
+ * better accessibility support for your application. This is especially
+ * true for views that do not have textual representation (For example,
+ * ImageButton).
+ *
+ * @return The content descriptiopn.
+ *
+ * @attr ref android.R.styleable#View_contentDescription
+ */
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Sets the {@link View} description. It briefly describes the view and is
+ * primarily used for accessibility support. Set this property to enable
+ * better accessibility support for your application. This is especially
+ * true for views that do not have textual representation (For example,
+ * ImageButton).
+ *
+ * @param contentDescription The content description.
+ *
+ * @attr ref android.R.styleable#View_contentDescription
+ */
+ public void setContentDescription(CharSequence contentDescription) {
+ mContentDescription = contentDescription;
+ }
+
+ /**
* Invoked whenever this view loses focus, either by losing window focus or by losing
* focus within its window. This method can be used to clear any state tied to the
* focus. For instance, if a button is held pressed with the trackball and the window
@@ -3210,11 +3349,37 @@
* @param direction The direction of the focus
*/
public void addFocusables(ArrayList<View> views, int direction) {
- if (!isFocusable()) return;
+ addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
+ }
- if (isInTouchMode() && !isFocusableInTouchMode()) return;
+ /**
+ * Adds any focusable views that are descendants of this view (possibly
+ * including this view if it is focusable itself) to views. This method
+ * adds all focusable views regardless if we are in touch mode or
+ * only views focusable in touch mode if we are in touch mode depending on
+ * the focusable mode paramater.
+ *
+ * @param views Focusable views found so far or null if all we are interested is
+ * the number of focusables.
+ * @param direction The direction of the focus.
+ * @param focusableMode The type of focusables to be added.
+ *
+ * @see #FOCUSABLES_ALL
+ * @see #FOCUSABLES_TOUCH_MODE
+ */
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+ if (!isFocusable()) {
+ return;
+ }
- views.add(this);
+ if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE &&
+ isInTouchMode() && !isFocusableInTouchMode()) {
+ return;
+ }
+
+ if (views != null) {
+ views.add(this);
+ }
}
/**
@@ -4558,7 +4723,35 @@
*/
@ViewDebug.ExportedProperty
public boolean isOpaque() {
- return mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE;
+ return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK;
+ }
+
+ private void computeOpaqueFlags() {
+ // Opaque if:
+ // - Has a background
+ // - Background is opaque
+ // - Doesn't have scrollbars or scrollbars are inside overlay
+
+ if (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE) {
+ mPrivateFlags |= OPAQUE_BACKGROUND;
+ } else {
+ mPrivateFlags &= ~OPAQUE_BACKGROUND;
+ }
+
+ final int flags = mViewFlags;
+ if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
+ (flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) {
+ mPrivateFlags |= OPAQUE_SCROLLBARS;
+ } else {
+ mPrivateFlags &= ~OPAQUE_SCROLLBARS;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ protected boolean hasOpaqueScrollbars() {
+ return (mPrivateFlags & OPAQUE_SCROLLBARS) == OPAQUE_SCROLLBARS;
}
/**
@@ -4885,6 +5078,7 @@
public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
mViewFlags ^= SCROLLBARS_HORIZONTAL;
+ computeOpaqueFlags();
recomputePadding();
}
}
@@ -4914,6 +5108,7 @@
public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
mViewFlags ^= SCROLLBARS_VERTICAL;
+ computeOpaqueFlags();
recomputePadding();
}
}
@@ -4942,6 +5137,7 @@
public void setScrollBarStyle(int style) {
if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
+ computeOpaqueFlags();
recomputePadding();
}
}
@@ -5641,7 +5837,7 @@
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
}
- if (ViewRoot.PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60002, hashCode());
}
@@ -5727,13 +5923,14 @@
final int restoreCount = canvas.save();
canvas.translate(-mScrollX, -mScrollY);
- mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;
+ mPrivateFlags |= DRAWN;
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
}
+ mPrivateFlags &= ~DIRTY_MASK;
dispatchDraw(canvas);
} else {
draw(canvas);
@@ -5780,7 +5977,7 @@
canvas = new Canvas(bitmap);
}
- if ((backgroundColor&0xff000000) != 0) {
+ if ((backgroundColor & 0xff000000) != 0) {
bitmap.eraseColor(backgroundColor);
}
@@ -5788,6 +5985,10 @@
final int restoreCount = canvas.save();
canvas.translate(-mScrollX, -mScrollY);
+ // Temporarily remove the dirty mask
+ int flags = mPrivateFlags;
+ mPrivateFlags &= ~DIRTY_MASK;
+
// Fast path for layouts with no backgrounds
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
dispatchDraw(canvas);
@@ -5795,6 +5996,8 @@
draw(canvas);
}
+ mPrivateFlags = flags;
+
canvas.restoreToCount(restoreCount);
if (attachInfo != null) {
@@ -5915,8 +6118,10 @@
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
}
- final boolean dirtyOpaque = (mPrivateFlags & DIRTY_MASK) == DIRTY_OPAQUE;
- mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;
+ final int privateFlags = mPrivateFlags;
+ final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&
+ (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
+ mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN;
/*
* Draw traversal performs several drawing steps which must be executed
@@ -6697,6 +6902,8 @@
requestLayout = true;
}
+ computeOpaqueFlags();
+
if (requestLayout) {
requestLayout();
}
@@ -7166,6 +7373,60 @@
}
/**
+ * @param consistency The type of consistency. See ViewDebug for more information.
+ *
+ * @hide
+ */
+ protected boolean dispatchConsistencyCheck(int consistency) {
+ return onConsistencyCheck(consistency);
+ }
+
+ /**
+ * Method that subclasses should implement to check their consistency. The type of
+ * consistency check is indicated by the bit field passed as a parameter.
+ *
+ * @param consistency The type of consistency. See ViewDebug for more information.
+ *
+ * @throws IllegalStateException if the view is in an inconsistent state.
+ *
+ * @hide
+ */
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = true;
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+ final boolean checkDrawing = (consistency & ViewDebug.CONSISTENCY_DRAWING) != 0;
+
+ if (checkLayout) {
+ if (getParent() == null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " does not have a parent.");
+ }
+
+ if (mAttachInfo == null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " is not attached to a window.");
+ }
+ }
+
+ if (checkDrawing) {
+ // Do not check the DIRTY/DRAWN flags because views can call invalidate()
+ // from their draw() method
+
+ if ((mPrivateFlags & DRAWN) != DRAWN &&
+ (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + this + " was invalidated but its drawing cache is valid.");
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Prints information about this view in the log output, with the tag
* {@link #VIEW_LOG_TAG}.
*
@@ -8092,7 +8353,6 @@
* window.
*/
static class AttachInfo {
-
interface Callbacks {
void playSoundEffect(int effectId);
boolean performHapticFeedback(int effectId, boolean always);
@@ -8222,6 +8482,11 @@
long mDrawingTime;
/**
+ * Indicates whether or not ignoring the DIRTY_MASK flags.
+ */
+ boolean mIgnoreDirtyState;
+
+ /**
* Indicates whether the view's window is currently in touch mode.
*/
boolean mInTouchMode;
@@ -8299,7 +8564,12 @@
* calling up the hierarchy.
*/
final Rect mTmpInvalRect = new Rect();
-
+
+ /**
+ * Temporary list for use in collecting focusable descendents of a view.
+ */
+ final ArrayList<View> mFocusablesTempList = new ArrayList<View>(24);
+
/**
* Creates a new set of attachment information with the specified
* events handler and thread.
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 367c9a2..aaaadef 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -54,6 +54,27 @@
*/
public class ViewDebug {
/**
+ * Log tag used to log errors related to the consistency of the view hierarchy.
+ *
+ * @hide
+ */
+ public static final String CONSISTENCY_LOG_TAG = "ViewConsistency";
+
+ /**
+ * Flag indicating the consistency check should check layout-related properties.
+ *
+ * @hide
+ */
+ public static final int CONSISTENCY_LAYOUT = 0x1;
+
+ /**
+ * Flag indicating the consistency check should check drawing-related properties.
+ *
+ * @hide
+ */
+ public static final int CONSISTENCY_DRAWING = 0x2;
+
+ /**
* Enables or disables view hierarchy tracing. Any invoker of
* {@link #trace(View, android.view.ViewDebug.HierarchyTraceType)} should first
* check that this value is set to true as not to affect performance.
@@ -80,6 +101,49 @@
static final String SYSTEM_PROPERTY_CAPTURE_EVENT = "debug.captureevent";
/**
+ * Profiles drawing times in the events log.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean profileDrawing = false;
+
+ /**
+ * Profiles layout times in the events log.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean profileLayout = false;
+
+ /**
+ * Profiles real fps (times between draws) and displays the result.
+ *
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean showFps = false;
+
+ /**
+ * <p>Enables or disables views consistency check. Even when this property is enabled,
+ * view consistency checks happen only if {@link android.util.Config#DEBUG} is set
+ * to true. The value of this property can be configured externally in one of the
+ * following files:</p>
+ * <ul>
+ * <li>/system/debug.prop</li>
+ * <li>/debug.prop</li>
+ * <li>/data/debug.prop</li>
+ * </ul>
+ * @hide
+ */
+ @Debug.DebugProperty
+ public static boolean consistencyCheckEnabled = false;
+
+ static {
+ Debug.setFieldsOn(ViewDebug.class, true);
+ }
+
+ /**
* This annotation can be used to mark fields and methods to be dumped by
* the view server. Only non-void methods with no arguments can be annotated
* by this annotation.
@@ -123,7 +187,7 @@
* of an array:
*
* <pre>
- * @ViewDebug.ExportedProperty(mapping = {
+ * @ViewDebug.ExportedProperty(indexMapping = {
* @ViewDebug.IntToString(from = 0, to = "INVALID"),
* @ViewDebug.IntToString(from = 1, to = "FIRST"),
* @ViewDebug.IntToString(from = 2, to = "SECOND")
@@ -139,6 +203,25 @@
IntToString[] indexMapping() default { };
/**
+ * A flags mapping can be defined to map flags encoded in an integer to
+ * specific strings. A mapping can be used to see human readable values
+ * for the flags of an integer:
+ *
+ * <pre>
+ * @ViewDebug.ExportedProperty(flagMapping = {
+ * @ViewDebug.FlagToString(mask = ENABLED_MASK, equals = ENABLED, name = "ENABLED"),
+ * @ViewDebug.FlagToString(mask = ENABLED_MASK, equals = DISABLED, name = "DISABLED"),
+ * })
+ * private int mFlags;
+ * <pre>
+ *
+ * A specified String is output when the following is true:
+ *
+ * @return An array of int to String mappings
+ */
+ FlagToString[] flagMapping() default { };
+
+ /**
* When deep export is turned on, this property is not dumped. Instead, the
* properties contained in this property are dumped. Each child property
* is prefixed with the name of this property.
@@ -182,7 +265,45 @@
*/
String to();
}
-
+
+ /**
+ * Defines a mapping from an flag to a String. Such a mapping can be used
+ * in a @ExportedProperty to provide more meaningful values to the end user.
+ *
+ * @see android.view.ViewDebug.ExportedProperty
+ */
+ @Target({ ElementType.TYPE })
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface FlagToString {
+ /**
+ * The mask to apply to the original value.
+ *
+ * @return An arbitrary int value.
+ */
+ int mask();
+
+ /**
+ * The value to compare to the result of:
+ * <code>original value & {@link #mask()}</code>.
+ *
+ * @return An arbitrary value.
+ */
+ int equals();
+
+ /**
+ * The String to use in place of the original int value.
+ *
+ * @return An arbitrary non-null String.
+ */
+ String name();
+
+ /**
+ * Indicates whether to output the flag when the test is true,
+ * or false. Defaults to true.
+ */
+ boolean outputIf() default true;
+ }
+
/**
* This annotation can be used to mark fields and methods to be dumped when
* the view is captured. Methods with this annotation must have no arguments
@@ -975,6 +1096,13 @@
final int id = (Integer) methodValue;
methodValue = resolveId(context, id);
} else {
+ final FlagToString[] flagsMapping = property.flagMapping();
+ if (flagsMapping.length > 0) {
+ final int intValue = (Integer) methodValue;
+ final String valuePrefix = prefix + method.getName() + '_';
+ exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
+ }
+
final IntToString[] mapping = property.mapping();
if (mapping.length > 0) {
final int intValue = (Integer) methodValue;
@@ -1036,6 +1164,13 @@
final int id = field.getInt(view);
fieldValue = resolveId(context, id);
} else {
+ final FlagToString[] flagsMapping = property.flagMapping();
+ if (flagsMapping.length > 0) {
+ final int intValue = field.getInt(view);
+ final String valuePrefix = prefix + field.getName() + '_';
+ exportUnrolledFlags(out, flagsMapping, intValue, valuePrefix);
+ }
+
final IntToString[] mapping = property.mapping();
if (mapping.length > 0) {
final int intValue = field.getInt(view);
@@ -1093,6 +1228,23 @@
out.write(' ');
}
+ private static void exportUnrolledFlags(BufferedWriter out, FlagToString[] mapping,
+ int intValue, String prefix) throws IOException {
+
+ final int count = mapping.length;
+ for (int j = 0; j < count; j++) {
+ final FlagToString flagMapping = mapping[j];
+ final boolean ifTrue = flagMapping.outputIf();
+ final int maskResult = intValue & flagMapping.mask();
+ final boolean test = maskResult == flagMapping.equals();
+ if ((test && ifTrue) || (!test && !ifTrue)) {
+ final String name = flagMapping.name();
+ final String value = "0x" + Integer.toHexString(maskResult);
+ writeEntry(out, prefix, name, "", value);
+ }
+ }
+ }
+
private static void exportUnrolledArray(Context context, BufferedWriter out,
ExportedProperty property, int[] array, String prefix, String suffix)
throws IOException {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 31159d7..bf04dcd 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -24,14 +24,16 @@
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.RectF;
+import android.graphics.Region;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.Config;
import android.util.EventLog;
import android.util.Log;
import android.util.SparseArray;
+import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
@@ -600,6 +602,14 @@
*/
@Override
public void addFocusables(ArrayList<View> views, int direction) {
+ addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
final int focusableCount = views.size();
final int descendantFocusability = getDescendantFocusability();
@@ -611,7 +621,7 @@
for (int i = 0; i < count; i++) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
- child.addFocusables(views, direction);
+ child.addFocusables(views, direction, focusableMode);
}
}
}
@@ -624,7 +634,7 @@
descendantFocusability != FOCUS_AFTER_DESCENDANTS ||
// No focusable descendants
(focusableCount == views.size())) {
- super.addFocusables(views, direction);
+ super.addFocusables(views, direction, focusableMode);
}
}
@@ -1019,6 +1029,15 @@
}
}
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean populated = false;
+ for (int i = 0, count = getChildCount(); i < count; i++) {
+ populated |= getChildAt(i).dispatchPopulateAccessibilityEvent(event);
+ }
+ return populated;
+ }
+
/**
* {@inheritDoc}
*/
@@ -1402,7 +1421,7 @@
}
}
- // Clear the flag as early as possible to allow draw() implementations
+ // Sets the flag as early as possible to allow draw() implementations
// to call invalidate() successfully when doing animations
child.mPrivateFlags |= DRAWN;
@@ -1481,6 +1500,7 @@
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
}
+ child.mPrivateFlags &= ~DIRTY_MASK;
child.dispatchDraw(canvas);
} else {
child.draw(canvas);
@@ -1494,7 +1514,7 @@
cachePaint.setAlpha(255);
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
}
- if (ViewRoot.PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60003, hashCode());
}
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
@@ -2750,6 +2770,61 @@
}
/**
+ * @hide
+ */
+ @Override
+ protected boolean dispatchConsistencyCheck(int consistency) {
+ boolean result = super.dispatchConsistencyCheck(consistency);
+
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < count; i++) {
+ if (!children[i].dispatchConsistencyCheck(consistency)) result = false;
+ }
+
+ return result;
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = super.onConsistencyCheck(consistency);
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+ final boolean checkDrawing = (consistency & ViewDebug.CONSISTENCY_DRAWING) != 0;
+
+ if (checkLayout) {
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < count; i++) {
+ if (children[i].getParent() != this) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "View " + children[i] + " has no parent/a parent that is not " + this);
+ }
+ }
+ }
+
+ if (checkDrawing) {
+ // If this group is dirty, check that the parent is dirty as well
+ if ((mPrivateFlags & DIRTY_MASK) != 0) {
+ final ViewParent parent = getParent();
+ if (parent != null && !(parent instanceof ViewRoot)) {
+ if ((((View) parent).mPrivateFlags & DIRTY_MASK) == 0) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "ViewGroup " + this + " is dirty but its parent is not: " + this);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 8494d5e..7cd65e2 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -34,6 +34,8 @@
import android.util.EventLog;
import android.util.SparseArray;
import android.view.View.MeasureSpec;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
@@ -75,13 +77,6 @@
private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
private static final boolean WATCH_POINTER = false;
- static final boolean PROFILE_DRAWING = false;
- private static final boolean PROFILE_LAYOUT = false;
- // profiles real fps (times between draws) and displays the result
- private static final boolean SHOW_FPS = false;
- // used by SHOW_FPS
- private static int sDrawTime;
-
/**
* Maximum time we allow the user to roll the trackball enough to generate
* a key event, before resetting the counters.
@@ -97,6 +92,8 @@
static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>();
+ private static int sDrawTime;
+
long mLastTrackballTime = 0;
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
@@ -128,9 +125,10 @@
int mHeight;
Rect mDirty; // will be a graphics.Region soon
boolean mIsAnimating;
- // TODO: change these to scaler class.
- float mAppScale;
- float mAppScaleInverted; // = 1.0f / mAppScale
+ // TODO: change these to scalar class.
+ private float mAppScale;
+ private float mAppScaleInverted; // = 1.0f / mAppScale
+ private int[] mWindowLayoutParamsBackup = null;
final View.AttachInfo mAttachInfo;
@@ -389,6 +387,9 @@
if (mView == null) {
mView = view;
mAppScale = mView.getContext().getApplicationScale();
+ if (mAppScale != 1.0f) {
+ mWindowLayoutParamsBackup = new int[4];
+ }
mAppScaleInverted = 1.0f / mAppScale;
mWindowAttributes.copyFrom(attrs);
mSoftInputMode = attrs.softInputMode;
@@ -478,7 +479,6 @@
synchronized (this) {
int oldSoftInputMode = mWindowAttributes.softInputMode;
mWindowAttributes.copyFrom(attrs);
- mWindowAttributes.scale(mAppScale);
if (newView) {
mSoftInputMode = attrs.softInputMode;
@@ -539,7 +539,6 @@
}
dirty = mTempRect;
}
- // TODO: When doing a union with mDirty != empty, we must cancel all the DIRTY_OPAQUE flags
mDirty.union(dirty);
if (!mWillDrawSoon) {
scheduleTraversals();
@@ -643,6 +642,7 @@
host.dispatchAttachedToWindow(attachInfo, 0);
getRunQueue().executeActions(attachInfo.mHandler);
//Log.i(TAG, "Screen on initialized: " + attachInfo.mKeepScreenOn);
+
} else {
desiredWindowWidth = mWinFrame.width();
desiredWindowHeight = mWinFrame.height();
@@ -796,7 +796,7 @@
final Rect frame = mWinFrame;
boolean initialized = false;
boolean contentInsetsChanged = false;
- boolean visibleInsetsChanged = false;
+ boolean visibleInsetsChanged;
try {
boolean hadSurface = mSurface.isValid();
int fl = 0;
@@ -937,14 +937,22 @@
if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(
"ViewRoot", "Laying out " + host + " to (" +
host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")");
- long startTime;
- if (PROFILE_LAYOUT) {
+ long startTime = 0L;
+ if (Config.DEBUG && ViewDebug.profileLayout) {
startTime = SystemClock.elapsedRealtime();
}
host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);
- if (PROFILE_LAYOUT) {
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ if (!host.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_LAYOUT)) {
+ throw new IllegalStateException("The view hierarchy is an inconsistent state,"
+ + "please refer to the logs with the tag "
+ + ViewDebug.CONSISTENCY_LOG_TAG + " for more infomation.");
+ }
+ }
+
+ if (Config.DEBUG && ViewDebug.profileLayout) {
EventLog.writeEvent(60001, SystemClock.elapsedRealtime() - startTime);
}
@@ -960,10 +968,11 @@
mTmpLocation[1] + host.mBottom - host.mTop);
host.gatherTransparentRegion(mTransparentRegion);
- if (mAppScale != 1.0f) {
- mTransparentRegion.scale(mAppScale);
- }
+ // TODO: scale the region, like:
+ // Region uses native methods. We probabl should have ScalableRegion class.
+
+ // Region does not have equals method ?
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager
@@ -1135,8 +1144,7 @@
}
int yoff;
- final boolean scrolling = mScroller != null
- && mScroller.computeScrollOffset();
+ final boolean scrolling = mScroller != null && mScroller.computeScrollOffset();
if (scrolling) {
yoff = mScroller.getCurrY();
} else {
@@ -1151,13 +1159,14 @@
if (mUseGL) {
if (!dirty.isEmpty()) {
Canvas canvas = mGlCanvas;
- if (mGL!=null && canvas != null) {
+ if (mGL != null && canvas != null) {
mGL.glDisable(GL_SCISSOR_TEST);
mGL.glClearColor(0, 0, 0, 0);
mGL.glClear(GL_COLOR_BUFFER_BIT);
mGL.glEnable(GL_SCISSOR_TEST);
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
+ mAttachInfo.mIgnoreDirtyState = true;
mView.mPrivateFlags |= View.DRAWN;
float scale = mAppScale;
@@ -1168,14 +1177,19 @@
canvas.scale(scale, scale);
}
mView.draw(canvas);
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
} finally {
canvas.restoreToCount(saveCount);
}
+ mAttachInfo.mIgnoreDirtyState = false;
+
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
checkEglErrors();
- if (SHOW_FPS) {
+ if (Config.DEBUG && ViewDebug.showFps) {
int now = (int)SystemClock.elapsedRealtime();
if (sDrawTime != 0) {
nativeShowFPS(canvas, now - sDrawTime);
@@ -1191,8 +1205,10 @@
return;
}
- if (fullRedrawNeeded)
+ if (fullRedrawNeeded) {
+ mAttachInfo.mIgnoreDirtyState = true;
dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
+ }
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
Log.v("ViewRoot", "Draw " + mView + "/"
@@ -1204,7 +1220,18 @@
Canvas canvas;
try {
+ int left = dirty.left;
+ int top = dirty.top;
+ int right = dirty.right;
+ int bottom = dirty.bottom;
+
canvas = surface.lockCanvas(dirty);
+
+ if (left != dirty.left || top != dirty.top || right != dirty.right ||
+ bottom != dirty.bottom) {
+ mAttachInfo.mIgnoreDirtyState = true;
+ }
+
// TODO: Do this in native
canvas.setDensityScale(mDensity);
} catch (Surface.OutOfResourcesException e) {
@@ -1216,7 +1243,7 @@
try {
if (!dirty.isEmpty() || mIsAnimating) {
- long startTime;
+ long startTime = 0L;
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
@@ -1224,7 +1251,7 @@
//canvas.drawARGB(255, 255, 0, 0);
}
- if (PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
startTime = SystemClock.elapsedRealtime();
}
@@ -1232,12 +1259,11 @@
// need to clear it before drawing so that the child will
// properly re-composite its drawing on a transparent
// background. This automatically respects the clip/dirty region
- if (!canvas.isOpaque()) {
- canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
- } else if (yoff != 0) {
- // If we are applying an offset, we need to clear the area
- // where the offset doesn't appear to avoid having garbage
- // left in the blank areas.
+ // or
+ // If we are applying an offset, we need to clear the area
+ // where the offset doesn't appear to avoid having garbage
+ // left in the blank areas.
+ if (!canvas.isOpaque() || yoff != 0) {
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
}
@@ -1247,9 +1273,10 @@
mView.mPrivateFlags |= View.DRAWN;
float scale = mAppScale;
- Context cxt = mView.getContext();
if (DEBUG_DRAW) {
- Log.i(TAG, "Drawing: package:" + cxt.getPackageName() + ", appScale=" + mAppScale);
+ Context cxt = mView.getContext();
+ Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
+ ", appScale=" + mAppScale);
}
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
try {
@@ -1260,10 +1287,15 @@
}
mView.draw(canvas);
} finally {
+ mAttachInfo.mIgnoreDirtyState = false;
canvas.restoreToCount(saveCount);
}
- if (SHOW_FPS) {
+ if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
+ mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
+ }
+
+ if (Config.DEBUG && ViewDebug.showFps) {
int now = (int)SystemClock.elapsedRealtime();
if (sDrawTime != 0) {
nativeShowFPS(canvas, now - sDrawTime);
@@ -1271,7 +1303,7 @@
sDrawTime = now;
}
- if (PROFILE_DRAWING) {
+ if (Config.DEBUG && ViewDebug.profileDrawing) {
EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
}
}
@@ -1694,7 +1726,7 @@
}
mView.dispatchWindowFocusChanged(hasWindowFocus);
}
-
+
// Note: must be done after the focus change callbacks,
// so all of the view state is set up correctly.
if (hasWindowFocus) {
@@ -1712,6 +1744,10 @@
~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
mHasHadWindowFocus = true;
}
+
+ if (hasWindowFocus && mView != null) {
+ sendAccessibilityEvents();
+ }
}
} break;
case DIE:
@@ -1878,6 +1914,9 @@
} else {
didFinish = false;
}
+ if (event != null) {
+ event.scale(mAppScaleInverted);
+ }
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
@@ -2306,12 +2345,22 @@
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
+
+ boolean restore = false;
+ if (params != null && mAppScale != 1.0f) {
+ restore = true;
+ params.scale(mAppScale, mWindowLayoutParamsBackup);
+ }
int relayoutResult = sWindowSession.relayout(
mWindow, params,
(int) (mView.mMeasuredWidth * mAppScale),
(int) (mView.mMeasuredHeight * mAppScale),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets, mSurface);
+ if (restore) {
+ params.restore(mWindowLayoutParamsBackup);
+ }
+
mPendingContentInsets.scale(mAppScaleInverted);
mPendingVisibleInsets.scale(mAppScaleInverted);
mWinFrame.scale(mAppScaleInverted);
@@ -2413,7 +2462,7 @@
msg.arg2 = handled ? 1 : 0;
sendMessage(msg);
}
-
+
public void dispatchResized(int w, int h, Rect coveredInsets,
Rect visibleInsets, boolean reportDraw) {
if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": w=" + w
@@ -2484,6 +2533,21 @@
sendMessage(msg);
}
+ /**
+ * The window is getting focus so if there is anything focused/selected
+ * send an {@link AccessibilityEvent} to announce that.
+ */
+ private void sendAccessibilityEvents() {
+ if (!AccessibilityManager.getInstance(mView.getContext()).isEnabled()) {
+ return;
+ }
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ View focusedView = mView.findFocus();
+ if (focusedView != null && focusedView != mView) {
+ focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ }
+ }
+
public boolean showContextMenuForChild(View originalView) {
return false;
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 428de67..b0e738c 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -24,7 +24,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
-import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
/**
* Abstract base class for a top-level window look and behavior policy. An
@@ -153,7 +153,16 @@
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTrackballEvent(MotionEvent event);
-
+
+ /**
+ * Called to process population of {@link AccessibilityEvent}s.
+ *
+ * @param event The event.
+ *
+ * @return boolean Return true if event population was completed.
+ */
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
+
/**
* Instantiate the view to display in the panel for 'featureId'.
* You can return null, in which case the default content (typically
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index f6a171d..72ef0ad 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -18,6 +18,7 @@
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -465,6 +466,15 @@
*/
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
+ /** Window flag: special flag to let windows be shown when the screen
+ * is locked. This will let application windows take precedence over
+ * key guard or any other lock screens. Can be used with
+ * {@link #FLAG_KEEP_SCREEN_ON} to turn screen on and display windows
+ * directly before showing the key guard window
+ *
+ * {@hide} */
+ public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
+
/** Window flag: a special option intended for system dialogs. When
* this flag is set, the window will demand focus unconditionally when
* it is created.
@@ -954,19 +964,42 @@
return sb.toString();
}
- void scale(float scale) {
+ /**
+ * Scale the layout params' coordinates and size.
+ * Returns the original info as a backup so that the caller can
+ * restore the layout params;
+ */
+ void scale(float scale, int[] backup) {
if (scale != 1.0f) {
+ backup[0] = x;
+ backup[1] = y;
x *= scale;
y *= scale;
if (width > 0) {
+ backup[2] = width;
width *= scale;
}
if (height > 0) {
+ backup[3] = height;
height *= scale;
}
}
}
+ /**
+ * Restore the layout params' coordinates and size.
+ */
+ void restore(int[] backup) {
+ x = backup[0];
+ y = backup[1];
+ if (width > 0) {
+ width = backup[2];
+ }
+ if (height > 0) {
+ height = backup[3];
+ }
+ }
+
private CharSequence mTitle = "";
}
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 755d7b8..0973599 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -173,7 +173,6 @@
mRoots[index] = root;
mParams[index] = wparams;
}
-
// do this last because it fires off messages to start doing things
root.setView(view, wparams, panelParentView);
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.aidl b/core/java/android/view/accessibility/AccessibilityEvent.aidl
new file mode 100644
index 0000000..cee3604
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityEvent.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+parcelable AccessibilityEvent;
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
new file mode 100644
index 0000000..c22f991
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents accessibility events that are sent by the system when
+ * something notable happens in the user interface. For example, when a
+ * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc.
+ * <p>
+ * This class represents various semantically different accessibility event
+ * types. Each event type has associated a set of related properties. In other
+ * words, each event type is characterized via a subset of the properties exposed
+ * by this class. For each event type there is a corresponding constant defined
+ * in this class. Since some event types are semantically close there are mask
+ * constants that group them together. Follows a specification of the event
+ * types and their associated properties:
+ * <p>
+ * <b>VIEW TYPES</b> <br>
+ * <p>
+ * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View}
+ * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
+ * Type:{@link #TYPE_VIEW_CLICKED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()},
+ * {@link #isChecked()},
+ * {@link #isEnabled()},
+ * {@link #isPassword()},
+ * {@link #getItemCount()},
+ * {@link #getCurrentItemIndex()}
+ * <p>
+ * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View}
+ * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
+ * Type:{@link #TYPE_VIEW_LONG_CLICKED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()},
+ * {@link #isChecked()},
+ * {@link #isEnabled()},
+ * {@link #isPassword()},
+ * {@link #getItemCount()},
+ * {@link #getCurrentItemIndex()}
+ * <p>
+ * <b>View selected</b> - represents the event of selecting an item usually in
+ * the context of an {@link android.widget.AdapterView}. <br>
+ * Type: {@link #TYPE_VIEW_SELECTED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()},
+ * {@link #isChecked()},
+ * {@link #isEnabled()},
+ * {@link #isPassword()},
+ * {@link #getItemCount()},
+ * {@link #getCurrentItemIndex()}
+ * <p>
+ * <b>View focused</b> - represents the event of focusing a
+ * {@link android.view.View}. <br>
+ * Type: {@link #TYPE_VIEW_FOCUSED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()},
+ * {@link #isChecked()},
+ * {@link #isEnabled()},
+ * {@link #isPassword()},
+ * {@link #getItemCount()},
+ * {@link #getCurrentItemIndex()}
+ * <p>
+ * <b>View text changed</b> - represents the event of changing the text of an
+ * {@link android.widget.EditText}. <br>
+ * Type: {@link #TYPE_VIEW_TEXT_CHANGED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()},
+ * {@link #isChecked()},
+ * {@link #isEnabled()},
+ * {@link #isPassword()},
+ * {@link #getItemCount()},
+ * {@link #getCurrentItemIndex()},
+ * {@link #getFromIndex()},
+ * {@link #getAddedCount()},
+ * {@link #getRemovedCount()},
+ * {@link #getBeforeText()}
+ * <p>
+ * <b>TRANSITION TYPES</b> <br>
+ * <p>
+ * <b>Window state changed</b> - represents the event of opening/closing a
+ * {@link android.widget.PopupWindow}, {@link android.view.Menu},
+ * {@link android.app.Dialog}, etc. <br>
+ * Type: {@link #TYPE_WINDOW_STATE_CHANGED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()}
+ * <p>
+ * <b>NOTIFICATION TYPES</b> <br>
+ * <p>
+ * <b>Notification state changed</b> - represents the event showing/hiding
+ * {@link android.app.Notification}.
+ * Type: {@link #TYPE_NOTIFICATION_STATE_CHANGED} <br>
+ * Properties:
+ * {@link #getClassName()},
+ * {@link #getPackageName()},
+ * {@link #getEventTime()},
+ * {@link #getText()}
+ * {@link #getParcelableData()}
+ * <p>
+ * <b>Security note</b>
+ * <p>
+ * Since an event contains the text of its source privacy can be compromised by leaking of
+ * sensitive information such as passwords. To address this issue any event fired in response
+ * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
+ *
+ * @see android.view.accessibility.AccessibilityManager
+ * @see android.accessibilityservice.AccessibilityService
+ */
+public final class AccessibilityEvent implements Parcelable {
+
+ /**
+ * Invalid selection/focus position.
+ *
+ * @see #getCurrentItemIndex()
+ */
+ public static final int INVALID_POSITION = -1;
+
+ /**
+ * Maximum length of the text fields.
+ *
+ * @see #getBeforeText()
+ * @see #getText()
+ */
+ public static final int MAX_TEXT_LENGTH = 500;
+
+ /**
+ * Represents the event of clicking on a {@link android.view.View} like
+ * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
+ */
+ public static final int TYPE_VIEW_CLICKED = 0x00000001;
+
+ /**
+ * Represents the event of long clicking on a {@link android.view.View} like
+ * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
+ */
+ public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;
+
+ /**
+ * Represents the event of selecting an item usually in the context of an
+ * {@link android.widget.AdapterView}.
+ */
+ public static final int TYPE_VIEW_SELECTED = 0x00000004;
+
+ /**
+ * Represents the event of focusing a {@link android.view.View}.
+ */
+ public static final int TYPE_VIEW_FOCUSED = 0x00000008;
+
+ /**
+ * Represents the event of changing the text of an {@link android.widget.EditText}.
+ */
+ public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
+
+ /**
+ * Represents the event of opening/closing a {@link android.widget.PopupWindow},
+ * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
+ */
+ public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
+
+ /**
+ * Represents the event showing/hiding a {@link android.app.Notification}.
+ */
+ public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;
+
+ /**
+ * Mask for {@link AccessibilityEvent} all types.
+ *
+ * @see #TYPE_VIEW_CLICKED
+ * @see #TYPE_VIEW_LONG_CLICKED
+ * @see #TYPE_VIEW_SELECTED
+ * @see #TYPE_VIEW_FOCUSED
+ * @see #TYPE_VIEW_TEXT_CHANGED
+ * @see #TYPE_WINDOW_STATE_CHANGED
+ * @see #TYPE_NOTIFICATION_STATE_CHANGED
+ */
+ public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
+
+ private static final int MAX_POOL_SIZE = 2;
+ private static final Object mPoolLock = new Object();
+ private static AccessibilityEvent sPool;
+ private static int sPoolSize;
+
+ private static final int CHECKED = 0x00000001;
+ private static final int ENABLED = 0x00000002;
+ private static final int PASSWORD = 0x00000004;
+ private static final int FULL_SCREEN = 0x00000080;
+
+ private AccessibilityEvent mNext;
+
+ private int mEventType;
+ private int mBooleanProperties;
+ private int mCurrentItemIndex;
+ private int mItemCount;
+ private int mFromIndex;
+ private int mAddedCount;
+ private int mRemovedCount;
+
+ private long mEventTime;
+
+ private CharSequence mClassName;
+ private CharSequence mPackageName;
+ private CharSequence mContentDescription;
+ private CharSequence mBeforeText;
+
+ private Parcelable mParcelableData;
+
+ private final List<CharSequence> mText = new ArrayList<CharSequence>();
+
+ private boolean mIsInPool;
+
+ /*
+ * Hide constructor from clients.
+ */
+ private AccessibilityEvent() {
+ mCurrentItemIndex = INVALID_POSITION;
+ }
+
+ /**
+ * Gets if the source is checked.
+ *
+ * @return True if the view is checked, false otherwise.
+ */
+ public boolean isChecked() {
+ return getBooleanProperty(CHECKED);
+ }
+
+ /**
+ * Sets if the source is checked.
+ *
+ * @param isChecked True if the view is checked, false otherwise.
+ */
+ public void setChecked(boolean isChecked) {
+ setBooleanProperty(CHECKED, isChecked);
+ }
+
+ /**
+ * Gets if the source is enabled.
+ *
+ * @return True if the view is enabled, false otherwise.
+ */
+ public boolean isEnabled() {
+ return getBooleanProperty(ENABLED);
+ }
+
+ /**
+ * Sets if the source is enabled.
+ *
+ * @param isEnabled True if the view is enabled, false otherwise.
+ */
+ public void setEnabled(boolean isEnabled) {
+ setBooleanProperty(ENABLED, isEnabled);
+ }
+
+ /**
+ * Gets if the source is a password field.
+ *
+ * @return True if the view is a password field, false otherwise.
+ */
+ public boolean isPassword() {
+ return getBooleanProperty(PASSWORD);
+ }
+
+ /**
+ * Sets if the source is a password field.
+ *
+ * @param isPassword True if the view is a password field, false otherwise.
+ */
+ public void setPassword(boolean isPassword) {
+ setBooleanProperty(PASSWORD, isPassword);
+ }
+
+ /**
+ * Sets if the source is taking the entire screen.
+ *
+ * @param isFullScreen True if the source is full screen, false otherwise.
+ */
+ public void setFullScreen(boolean isFullScreen) {
+ setBooleanProperty(FULL_SCREEN, isFullScreen);
+ }
+
+ /**
+ * Gets if the source is taking the entire screen.
+ *
+ * @return True if the source is full screen, false otherwise.
+ */
+ public boolean isFullScreen() {
+ return getBooleanProperty(FULL_SCREEN);
+ }
+
+ /**
+ * Gets the event type.
+ *
+ * @return The event type.
+ */
+ public int getEventType() {
+ return mEventType;
+ }
+
+ /**
+ * Sets the event type.
+ *
+ * @param eventType The event type.
+ */
+ public void setEventType(int eventType) {
+ mEventType = eventType;
+ }
+
+ /**
+ * Gets the number of items that can be visited.
+ *
+ * @return The number of items.
+ */
+ public int getItemCount() {
+ return mItemCount;
+ }
+
+ /**
+ * Sets the number of items that can be visited.
+ *
+ * @param itemCount The number of items.
+ */
+ public void setItemCount(int itemCount) {
+ mItemCount = itemCount;
+ }
+
+ /**
+ * Gets the index of the source in the list of items the can be visited.
+ *
+ * @return The current item index.
+ */
+ public int getCurrentItemIndex() {
+ return mCurrentItemIndex;
+ }
+
+ /**
+ * Sets the index of the source in the list of items that can be visited.
+ *
+ * @param currentItemIndex The current item index.
+ */
+ public void setCurrentItemIndex(int currentItemIndex) {
+ mCurrentItemIndex = currentItemIndex;
+ }
+
+ /**
+ * Gets the index of the first character of the changed sequence.
+ *
+ * @return The index of the first character.
+ */
+ public int getFromIndex() {
+ return mFromIndex;
+ }
+
+ /**
+ * Sets the index of the first character of the changed sequence.
+ *
+ * @param fromIndex The index of the first character.
+ */
+ public void setFromIndex(int fromIndex) {
+ mFromIndex = fromIndex;
+ }
+
+ /**
+ * Gets the number of added characters.
+ *
+ * @return The number of added characters.
+ */
+ public int getAddedCount() {
+ return mAddedCount;
+ }
+
+ /**
+ * Sets the number of added characters.
+ *
+ * @param addedCount The number of added characters.
+ */
+ public void setAddedCount(int addedCount) {
+ mAddedCount = addedCount;
+ }
+
+ /**
+ * Gets the number of removed characters.
+ *
+ * @return The number of removed characters.
+ */
+ public int getRemovedCount() {
+ return mRemovedCount;
+ }
+
+ /**
+ * Sets the number of removed characters.
+ *
+ * @param removedCount The number of removed characters.
+ */
+ public void setRemovedCount(int removedCount) {
+ mRemovedCount = removedCount;
+ }
+
+ /**
+ * Gets the time in which this event was sent.
+ *
+ * @return The event time.
+ */
+ public long getEventTime() {
+ return mEventTime;
+ }
+
+ /**
+ * Sets the time in which this event was sent.
+ *
+ * @param eventTime The event time.
+ */
+ public void setEventTime(long eventTime) {
+ mEventTime = eventTime;
+ }
+
+ /**
+ * Gets the class name of the source.
+ *
+ * @return The class name.
+ */
+ public CharSequence getClassName() {
+ return mClassName;
+ }
+
+ /**
+ * Sets the class name of the source.
+ *
+ * @param className The lass name.
+ */
+ public void setClassName(CharSequence className) {
+ mClassName = className;
+ }
+
+ /**
+ * Gets the package name of the source.
+ *
+ * @return The package name.
+ */
+ public CharSequence getPackageName() {
+ return mPackageName;
+ }
+
+ /**
+ * Sets the package name of the source.
+ *
+ * @param packageName The package name.
+ */
+ public void setPackageName(CharSequence packageName) {
+ mPackageName = packageName;
+ }
+
+ /**
+ * Gets the text of the event. The index in the list represents the priority
+ * of the text. Specifically, the lower the index the higher the priority.
+ *
+ * @return The text.
+ */
+ public List<CharSequence> getText() {
+ return mText;
+ }
+
+ /**
+ * Sets the text before a change.
+ *
+ * @return The text before the change.
+ */
+ public CharSequence getBeforeText() {
+ return mBeforeText;
+ }
+
+ /**
+ * Sets the text before a change.
+ *
+ * @param beforeText The text before the change.
+ */
+ public void setBeforeText(CharSequence beforeText) {
+ mBeforeText = beforeText;
+ }
+
+ /**
+ * Gets the description of the source.
+ *
+ * @return The description.
+ */
+ public CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Sets the description of the source.
+ *
+ * @param contentDescription The description.
+ */
+ public void setContentDescription(CharSequence contentDescription) {
+ mContentDescription = contentDescription;
+ }
+
+ /**
+ * Gets the {@link Parcelable} data.
+ *
+ * @return The parcelable data.
+ */
+ public Parcelable getParcelableData() {
+ return mParcelableData;
+ }
+
+ /**
+ * Sets the {@link Parcelable} data of the event.
+ *
+ * @param parcelableData The parcelable data.
+ */
+ public void setParcelableData(Parcelable parcelableData) {
+ mParcelableData = parcelableData;
+ }
+
+ /**
+ * Returns a cached instance if such is available or a new one is
+ * instantiated with type property set.
+ *
+ * @param eventType The event type.
+ * @return An instance.
+ */
+ public static AccessibilityEvent obtain(int eventType) {
+ AccessibilityEvent event = AccessibilityEvent.obtain();
+ event.setEventType(eventType);
+ return event;
+ }
+
+ /**
+ * Returns a cached instance if such is available or a new one is
+ * instantiated.
+ *
+ * @return An instance.
+ */
+ public static AccessibilityEvent obtain() {
+ synchronized (mPoolLock) {
+ if (sPool != null) {
+ AccessibilityEvent event = sPool;
+ sPool = sPool.mNext;
+ sPoolSize--;
+ event.mNext = null;
+ event.mIsInPool = false;
+ return event;
+ }
+ return new AccessibilityEvent();
+ }
+ }
+
+ /**
+ * Return an instance back to be reused.
+ * <p>
+ * <b>Note: You must not touch the object after calling this function.</b>
+ */
+ public void recycle() {
+ if (mIsInPool) {
+ return;
+ }
+
+ clear();
+ synchronized (mPoolLock) {
+ if (sPoolSize <= MAX_POOL_SIZE) {
+ mNext = sPool;
+ sPool = this;
+ mIsInPool = true;
+ sPoolSize++;
+ }
+ }
+ }
+
+ /**
+ * Clears the state of this instance.
+ */
+ private void clear() {
+ mEventType = 0;
+ mBooleanProperties = 0;
+ mCurrentItemIndex = INVALID_POSITION;
+ mItemCount = 0;
+ mFromIndex = 0;
+ mAddedCount = 0;
+ mRemovedCount = 0;
+ mEventTime = 0;
+ mClassName = null;
+ mPackageName = null;
+ mContentDescription = null;
+ mBeforeText = null;
+ mText.clear();
+ }
+
+ /**
+ * Gets the value of a boolean property.
+ *
+ * @param property The property.
+ * @return The value.
+ */
+ private boolean getBooleanProperty(int property) {
+ return (mBooleanProperties & property) == property;
+ }
+
+ /**
+ * Sets a boolean property.
+ *
+ * @param property The property.
+ * @param value The value.
+ */
+ private void setBooleanProperty(int property, boolean value) {
+ if (value) {
+ mBooleanProperties |= property;
+ } else {
+ mBooleanProperties &= ~property;
+ }
+ }
+
+ /**
+ * Creates a new instance from a {@link Parcel}.
+ *
+ * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
+ */
+ public void initFromParcel(Parcel parcel) {
+ mEventType = parcel.readInt();
+ mBooleanProperties = parcel.readInt();
+ mCurrentItemIndex = parcel.readInt();
+ mItemCount = parcel.readInt();
+ mFromIndex = parcel.readInt();
+ mAddedCount = parcel.readInt();
+ mRemovedCount = parcel.readInt();
+ mEventTime = parcel.readLong();
+ mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ mParcelableData = parcel.readParcelable(null);
+ parcel.readList(mText, null);
+ }
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mEventType);
+ parcel.writeInt(mBooleanProperties);
+ parcel.writeInt(mCurrentItemIndex);
+ parcel.writeInt(mItemCount);
+ parcel.writeInt(mFromIndex);
+ parcel.writeInt(mAddedCount);
+ parcel.writeInt(mRemovedCount);
+ parcel.writeLong(mEventTime);
+ TextUtils.writeToParcel(mClassName, parcel, 0);
+ TextUtils.writeToParcel(mPackageName, parcel, 0);
+ TextUtils.writeToParcel(mContentDescription, parcel, 0);
+ TextUtils.writeToParcel(mBeforeText, parcel, 0);
+ parcel.writeParcelable(mParcelableData, flags);
+ parcel.writeList(mText);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(super.toString());
+ builder.append("; EventType: " + mEventType);
+ builder.append("; EventTime: " + mEventTime);
+ builder.append("; ClassName: " + mClassName);
+ builder.append("; PackageName: " + mPackageName);
+ builder.append("; Text: " + mText);
+ builder.append("; ContentDescription: " + mContentDescription);
+ builder.append("; ItemCount: " + mItemCount);
+ builder.append("; CurrentItemIndex: " + mCurrentItemIndex);
+ builder.append("; IsEnabled: " + isEnabled());
+ builder.append("; IsPassword: " + isPassword());
+ builder.append("; IsChecked: " + isChecked());
+ builder.append("; IsFullScreen: " + isFullScreen());
+ builder.append("; BeforeText: " + mBeforeText);
+ builder.append("; FromIndex: " + mFromIndex);
+ builder.append("; AddedCount: " + mAddedCount);
+ builder.append("; RemovedCount: " + mRemovedCount);
+ builder.append("; ParcelableData: " + mParcelableData);
+ return builder.toString();
+ }
+
+ /**
+ * @see Parcelable.Creator
+ */
+ public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
+ new Parcelable.Creator<AccessibilityEvent>() {
+ public AccessibilityEvent createFromParcel(Parcel parcel) {
+ AccessibilityEvent event = AccessibilityEvent.obtain();
+ event.initFromParcel(parcel);
+ return event;
+ }
+
+ public AccessibilityEvent[] newArray(int size) {
+ return new AccessibilityEvent[size];
+ }
+ };
+}
diff --git a/core/java/android/view/accessibility/AccessibilityEventSource.java b/core/java/android/view/accessibility/AccessibilityEventSource.java
new file mode 100644
index 0000000..3d70959
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityEventSource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+/**
+ * This interface is implemented by classes source of {@link AccessibilityEvent}s.
+ */
+public interface AccessibilityEventSource {
+
+ /**
+ * Handles the request for sending an {@link AccessibilityEvent} given
+ * the event type. The method must first check if accessibility is on
+ * via calling {@link AccessibilityManager#isEnabled()}, obtain
+ * an {@link AccessibilityEvent} from the event pool through calling
+ * {@link AccessibilityEvent#obtain(int)}, populate the event, and
+ * send it for dispatch via calling
+ * {@link AccessibilityManager#sendAccessibilityEvent(AccessibilityEvent)}.
+ *
+ * @see AccessibilityEvent
+ * @see AccessibilityManager
+ *
+ * @param eventType The event type.
+ */
+ public void sendAccessibilityEvent(int eventType);
+
+ /**
+ * Handles the request for sending an {@link AccessibilityEvent}. The
+ * method does not guarantee to check if accessibility is on before
+ * sending the event for dispatch. It is responsibility of the caller
+ * to do the check via calling {@link AccessibilityManager#isEnabled()}.
+ *
+ * @see AccessibilityEvent
+ * @see AccessibilityManager
+ *
+ * @param event The event.
+ */
+ public void sendAccessibilityEventUnchecked(AccessibilityEvent event);
+}
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
new file mode 100644
index 0000000..0186270
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import static android.util.Config.LOGV;
+
+import android.content.Context;
+import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
+ * Such events are generated when something notable happens in the user interface,
+ * for example an {@link android.app.Activity} starts, the focus or selection of a
+ * {@link android.view.View} changes etc. Parties interested in handling accessibility
+ * events implement and register an accessibility service which extends
+ * {@link android.accessibilityservice.AccessibilityService}.
+ *
+ * @see AccessibilityEvent
+ * @see android.accessibilityservice.AccessibilityService
+ * @see android.content.Context#getSystemService
+ */
+public final class AccessibilityManager {
+ private static final String LOG_TAG = "AccessibilityManager";
+
+ static final Object sInstanceSync = new Object();
+
+ private static AccessibilityManager sInstance;
+
+ private static final int DO_SET_ENABLED = 10;
+
+ final IAccessibilityManager mService;
+
+ final Handler mHandler;
+
+ boolean mIsEnabled;
+
+ final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() {
+ public void setEnabled(boolean enabled) {
+ mHandler.obtainMessage(DO_SET_ENABLED, enabled ? 1 : 0, 0).sendToTarget();
+ }
+ };
+
+ class MyHandler extends Handler {
+
+ MyHandler(Looper mainLooper) {
+ super(mainLooper);
+ }
+
+ @Override
+ public void handleMessage(Message message) {
+ switch (message.what) {
+ case DO_SET_ENABLED :
+ synchronized (mHandler) {
+ mIsEnabled = (message.arg1 == 1);
+ }
+ return;
+ default :
+ Log.w(LOG_TAG, "Unknown message type: " + message.what);
+ }
+ }
+ }
+
+ /**
+ * Get an AccessibilityManager instance (create one if necessary).
+ *
+ * @hide
+ */
+ public static AccessibilityManager getInstance(Context context) {
+ synchronized (sInstanceSync) {
+ if (sInstance == null) {
+ sInstance = new AccessibilityManager(context);
+ }
+ }
+ return sInstance;
+ }
+
+ /**
+ * Create an instance.
+ *
+ * @param context A {@link Context}.
+ */
+ private AccessibilityManager(Context context) {
+ mHandler = new MyHandler(context.getMainLooper());
+ IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+ mService = IAccessibilityManager.Stub.asInterface(iBinder);
+ try {
+ mService.addClient(mClient);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
+ }
+ }
+
+ /**
+ * Returns if the {@link AccessibilityManager} is enabled.
+ *
+ * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
+ */
+ public boolean isEnabled() {
+ synchronized (mHandler) {
+ return mIsEnabled;
+ }
+ }
+
+ /**
+ * Sends an {@link AccessibilityEvent}. If this {@link AccessibilityManager} is not
+ * enabled the call is a NOOP.
+ *
+ * @param event The {@link AccessibilityEvent}.
+ *
+ * @throws IllegalStateException if a client tries to send an {@link AccessibilityEvent}
+ * while accessibility is not enabled.
+ */
+ public void sendAccessibilityEvent(AccessibilityEvent event) {
+ if (!mIsEnabled) {
+ throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+ }
+ boolean doRecycle = false;
+ try {
+ event.setEventTime(SystemClock.uptimeMillis());
+ // it is possible that this manager is in the same process as the service but
+ // client using it is called through Binder from another process. Example: MMS
+ // app adds a SMS notification and the NotificationManagerService calls this method
+ long identityToken = Binder.clearCallingIdentity();
+ doRecycle = mService.sendAccessibilityEvent(event);
+ Binder.restoreCallingIdentity(identityToken);
+ if (LOGV) {
+ Log.i(LOG_TAG, event + " sent");
+ }
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error during sending " + event + " ", re);
+ } finally {
+ if (doRecycle) {
+ event.recycle();
+ }
+ }
+ }
+
+ /**
+ * Requests interruption of the accessibility feedback from all accessibility services.
+ */
+ public void interrupt() {
+ if (!mIsEnabled) {
+ throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+ }
+ try {
+ mService.interrupt();
+ if (LOGV) {
+ Log.i(LOG_TAG, "Requested interrupt from all services");
+ }
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error while requesting interrupt from all services. ", re);
+ }
+ }
+
+ /**
+ * Returns the {@link ServiceInfo}s of the installed accessibility services.
+ *
+ * @return An unmodifiable list with {@link ServiceInfo}s.
+ */
+ public List<ServiceInfo> getAccessibilityServiceList() {
+ List<ServiceInfo> services = null;
+ try {
+ services = mService.getAccessibilityServiceList();
+ if (LOGV) {
+ Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
+ }
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re);
+ }
+ return Collections.unmodifiableList(services);
+ }
+}
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
new file mode 100644
index 0000000..32788be
--- /dev/null
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -0,0 +1,39 @@
+/* //device/java/android/android/app/INotificationManager.aidl
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.view.accessibility;
+
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.IAccessibilityManagerClient;
+import android.content.pm.ServiceInfo;
+
+/**
+ * Interface implemented by the AccessibilityManagerService called by
+ * the AccessibilityMasngers.
+ *
+ * @hide
+ */
+interface IAccessibilityManager {
+
+ void addClient(IAccessibilityManagerClient client);
+
+ boolean sendAccessibilityEvent(in AccessibilityEvent uiEvent);
+
+ List<ServiceInfo> getAccessibilityServiceList();
+
+ void interrupt();
+}
diff --git a/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
new file mode 100644
index 0000000..1eb60fc
--- /dev/null
+++ b/core/java/android/view/accessibility/IAccessibilityManagerClient.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+/**
+ * Interface a client of the IAccessibilityManager implements to
+ * receive information about changes in the manager state.
+ *
+ * @hide
+ */
+oneway interface IAccessibilityManagerClient {
+
+ void setEnabled(boolean enabled);
+
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a926355..563d819 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -21,6 +21,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
+import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -60,6 +61,7 @@
import android.webkit.TextDialog.AutoCompleteAdapter;
import android.webkit.WebViewCore.EventHub;
import android.widget.AbsoluteLayout;
+import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
@@ -4809,7 +4811,10 @@
@Override
public boolean hasStableIds() {
- return true;
+ // AdapterView's onChanged method uses this to determine whether
+ // to restore the old state. Return false so that the old (out
+ // of date) state does not replace the new, valid state.
+ return false;
}
private Container item(int position) {
@@ -4873,6 +4878,51 @@
}
}
+ /*
+ * Whenever the data set changes due to filtering, this class ensures
+ * that the checked item remains checked.
+ */
+ private class SingleDataSetObserver extends DataSetObserver {
+ private long mCheckedId;
+ private ListView mListView;
+ private Adapter mAdapter;
+
+ /*
+ * Create a new observer.
+ * @param id The ID of the item to keep checked.
+ * @param l ListView for getting and clearing the checked states
+ * @param a Adapter for getting the IDs
+ */
+ public SingleDataSetObserver(long id, ListView l, Adapter a) {
+ mCheckedId = id;
+ mListView = l;
+ mAdapter = a;
+ }
+
+ public void onChanged() {
+ // The filter may have changed which item is checked. Find the
+ // item that the ListView thinks is checked.
+ int position = mListView.getCheckedItemPosition();
+ long id = mAdapter.getItemId(position);
+ if (mCheckedId != id) {
+ // Clear the ListView's idea of the checked item, since
+ // it is incorrect
+ mListView.clearChoices();
+ // Search for mCheckedId. If it is in the filtered list,
+ // mark it as checked
+ int count = mAdapter.getCount();
+ for (int i = 0; i < count; i++) {
+ if (mAdapter.getItemId(i) == mCheckedId) {
+ mListView.setItemChecked(i, true);
+ break;
+ }
+ }
+ }
+ }
+
+ public void onInvalidate() {}
+ }
+
public void run() {
final ListView listView = (ListView) LayoutInflater.from(mContext)
.inflate(com.android.internal.R.layout.select_dialog, null);
@@ -4901,8 +4951,7 @@
// filtered. Do not allow filtering on multiple lists until
// that bug is fixed.
- // Disable filter altogether
- // listView.setTextFilterEnabled(!mMultiple);
+ listView.setTextFilterEnabled(!mMultiple);
if (mMultiple) {
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
int length = mSelectedArray.length;
@@ -4922,6 +4971,9 @@
listView.setSelection(mSelection);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setItemChecked(mSelection, true);
+ DataSetObserver observer = new SingleDataSetObserver(
+ adapter.getItemId(mSelection), listView, adapter);
+ adapter.registerDataSetObserver(observer);
}
}
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4f503b4..1ca59b2 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3190,7 +3190,7 @@
// Reclaim views on screen
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
- AbsListView.LayoutParams lp = (AbsListView.LayoutParams)child.getLayoutParams();
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
// Don't reclaim header or footer views, or views that should be ignored
if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
views.add(child);
@@ -3205,6 +3205,63 @@
}
/**
+ * @hide
+ */
+ @Override
+ protected boolean onConsistencyCheck(int consistency) {
+ boolean result = super.onConsistencyCheck(consistency);
+
+ final boolean checkLayout = (consistency & ViewDebug.CONSISTENCY_LAYOUT) != 0;
+
+ if (checkLayout) {
+ // The active recycler must be empty
+ final View[] activeViews = mRecycler.mActiveViews;
+ int count = activeViews.length;
+ for (int i = 0; i < count; i++) {
+ if (activeViews[i] != null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
+ "AbsListView " + this + " has a view in its active recycler: " +
+ activeViews[i]);
+ }
+ }
+
+ // All views in the recycler must NOT be on screen and must NOT have a parent
+ final ArrayList<View> scrap = mRecycler.mCurrentScrap;
+ if (!checkScrap(scrap)) result = false;
+ final ArrayList<View>[] scraps = mRecycler.mScrapViews;
+ count = scraps.length;
+ for (int i = 0; i < count; i++) {
+ if (!checkScrap(scraps[i])) result = false;
+ }
+ }
+
+ return result;
+ }
+
+ private boolean checkScrap(ArrayList<View> scrap) {
+ if (scrap == null) return true;
+ boolean result = true;
+
+ final int count = scrap.size();
+ for (int i = 0; i < count; i++) {
+ final View view = scrap.get(i);
+ if (view.getParent() != null) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, "AbsListView " + this +
+ " has a view in its scrap heap still attached to a parent: " + view);
+ }
+ if (indexOfChild(view) >= 0) {
+ result = false;
+ android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG, "AbsListView " + this +
+ " has a view in its scrap heap that is also a direct child: " + view);
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Sets the recycler listener to be notified whenever a View is set aside in
* the recycler for later reuse. This listener can be used to free resources
* associated to the View.
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 173e80f..7d2fcbc 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -24,11 +24,12 @@
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.ContextMenu;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewDebug;
import android.view.SoundEffectConstants;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.accessibility.AccessibilityEvent;
/**
@@ -618,7 +619,9 @@
}
/**
- * Sets the currently selected item
+ * Sets the currently selected item. To support accessibility subclasses that
+ * override this method must invoke the overriden super method first.
+ *
* @param position Index (starting at 0) of the data item to be selected.
*/
public abstract void setSelection(int position);
@@ -844,6 +847,11 @@
fireOnSelected();
}
}
+
+ // we fire selection events here not in View
+ if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
}
private void fireOnSelected() {
@@ -861,6 +869,35 @@
}
@Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean populated = false;
+ // This is an exceptional case which occurs when a window gets the
+ // focus and sends a focus event via its focused child to announce
+ // current focus/selection. AdapterView fires selection but not focus
+ // events so we change the event type here.
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+ event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
+
+ // we send selection events only from AdapterView to avoid
+ // generation of such event for each child
+ View selectedView = getSelectedView();
+ if (selectedView != null) {
+ populated = selectedView.dispatchPopulateAccessibilityEvent(event);
+ }
+
+ if (!populated) {
+ if (selectedView != null) {
+ event.setEnabled(selectedView.isEnabled());
+ }
+ event.setItemCount(getCount());
+ event.setCurrentItemIndex(getSelectedItemPosition());
+ }
+
+ return populated;
+ }
+
+ @Override
protected boolean canAnimate() {
return super.canAnimate() && mItemCount > 0;
}
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index c28210d..32e5504 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -348,7 +348,12 @@
"ArrayAdapter requires the resource ID to be a TextView", e);
}
- text.setText(getItem(position).toString());
+ T item = getItem(position);
+ if (item instanceof CharSequence) {
+ text.setText((CharSequence)item);
+ } else {
+ text.setText(item.toString());
+ }
return view;
}
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index abcc715..fd590ed 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -16,14 +16,15 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
-
-import com.android.internal.R;
+import android.view.accessibility.AccessibilityEvent;
/**
@@ -194,5 +195,13 @@
invalidate();
}
}
-
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean populated = super.dispatchPopulateAccessibilityEvent(event);
+ if (!populated) {
+ event.setChecked(mChecked);
+ }
+ return populated;
+ }
}
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index d4482dc..98b0976 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -26,7 +26,7 @@
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.Gravity;
-
+import android.view.accessibility.AccessibilityEvent;
/**
* <p>
@@ -124,6 +124,7 @@
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
+
mBroadcasting = false;
}
}
@@ -205,6 +206,25 @@
}
@Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean populated = super.dispatchPopulateAccessibilityEvent(event);
+
+ if (!populated) {
+ int resourceId = 0;
+ if (mChecked) {
+ resourceId = R.string.accessibility_compound_button_selected;
+ } else {
+ resourceId = R.string.accessibility_compound_button_unselected;
+ }
+ String state = getResources().getString(resourceId);
+ event.getText().add(state);
+ event.setChecked(mChecked);
+ }
+
+ return populated;
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
diff --git a/core/java/android/widget/ImageButton.java b/core/java/android/widget/ImageButton.java
index 4c1cbf6..d417e40 100644
--- a/core/java/android/widget/ImageButton.java
+++ b/core/java/android/widget/ImageButton.java
@@ -27,9 +27,35 @@
/**
* <p>
- * An image button displays an image that can be pressed, or clicked, by the
- * user.
- * </p>
+ * Displays a button with an image (instead of text) that can be pressed
+ * or clicked by the user. By default, an ImageButton looks like a regular
+ * {@link android.widget.Button}, with the standard button background
+ * that changes color during different button states. The image on the surface
+ * of the button is defined either by the {@code android:src} attribute in the
+ * {@code <ImageButton>} XML element or by the
+ * {@link #setImageResource(int)} method.</p>
+ *
+ * <p>To remove the standard button background image, define your own
+ * background image or set the background color to be transparent.</p>
+ * <p>To indicate the different button states (focused, selected, etc.), you can
+ * define a different image for each state. E.g., a blue image by default, an
+ * orange one for when focused, and a yellow one for when pressed. An easy way to
+ * do this is with an XML drawable "selector." For example:</p>
+ * <pre>
+ * <?xml version="1.0" encoding="utf-8"?>
+ * <selector xmlns:android="http://schemas.android.com/apk/res/android">
+ * <item android:drawable="@drawable/button_normal" /> <!-- default -->
+ * <item android:state_pressed="true"
+ * android:drawable="@drawable/button_pressed" /> <!-- pressed -->
+ * <item android:state_focused="true"
+ * android:drawable="@drawable/button_focused" /> <!-- focused -->
+ * </selector></pre>
+ *
+ * <p>Save the XML file in your project {@code res/drawable/} folder and then
+ * reference it as a drawable for the source of your ImageButton (in the
+ * {@code android:src} attribute). Android will automatically change the image
+ * based on the state of the button and the corresponding images
+ * defined in the XML.</p>
*
* <p><strong>XML attributes</strong></p>
* <p>
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 480b0b8..2796774 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -32,6 +32,8 @@
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.RemoteViews.RemoteView;
@@ -848,7 +850,7 @@
public int getBaseline() {
return mBaselineAligned ? getMeasuredHeight() : -1;
}
-
+
/**
* Set a tinting option for the image.
*
@@ -878,7 +880,7 @@
invalidate();
}
}
-
+
public void setAlpha(int alpha) {
alpha &= 0xFF; // keep it legal
if (mAlpha != alpha) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 5472d68..6686f75 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -21,6 +21,7 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.PixelFormat;
+import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Parcel;
@@ -35,6 +36,7 @@
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.SoundEffectConstants;
+import android.view.accessibility.AccessibilityEvent;
import com.google.android.collect.Lists;
import com.android.internal.R;
@@ -132,6 +134,7 @@
// used for temporary calculations.
private final Rect mTempRect = new Rect();
+ private Paint mDividerPaint;
// the single allocated result per list view; kinda cheesey but avoids
// allocating these thingies too often.
@@ -1845,6 +1848,32 @@
}
}
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean populated = super.dispatchPopulateAccessibilityEvent(event);
+
+ if (!populated) {
+ int itemCount = 0;
+ int currentItemIndex = getSelectedItemPosition();
+
+ ListAdapter adapter = getAdapter();
+ if (adapter != null) {
+ for (int i = 0, count = adapter.getCount(); i < count; i++) {
+ if (adapter.isEnabled(i)) {
+ itemCount++;
+ } else if (i <= currentItemIndex) {
+ currentItemIndex--;
+ }
+ }
+ }
+
+ event.setItemCount(itemCount);
+ event.setCurrentItemIndex(currentItemIndex);
+ }
+
+ return populated;
+ }
+
/**
* setSelectionAfterHeaderView set the selection to be the first list item
* after the header views.
@@ -2786,12 +2815,20 @@
*/
@Override
public boolean isOpaque() {
- return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque) || super.isOpaque();
+ return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque &&
+ hasOpaqueScrollbars()) || super.isOpaque();
}
@Override
public void setCacheColorHint(int color) {
- mIsCacheColorOpaque = (color >>> 24) == 0xFF;
+ final boolean opaque = (color >>> 24) == 0xFF;
+ mIsCacheColorOpaque = opaque;
+ if (opaque) {
+ if (mDividerPaint == null) {
+ mDividerPaint = new Paint();
+ }
+ mDividerPaint.setColor(color);
+ }
super.setCacheColorHint(color);
}
@@ -2814,6 +2851,8 @@
final int first = mFirstPosition;
final boolean areAllItemsSelectable = mAreAllItemsSelectable;
final ListAdapter adapter = mAdapter;
+ final boolean isOpaque = isOpaque();
+ final Paint paint = mDividerPaint;
if (!mStackFromBottom) {
int bottom;
@@ -2825,12 +2864,18 @@
View child = getChildAt(i);
bottom = child.getBottom();
// Don't draw dividers next to items that are not enabled
- if (bottom < listBottom && (areAllItemsSelectable ||
- (adapter.isEnabled(first + i) && (i == count - 1 ||
- adapter.isEnabled(first + i + 1))))) {
- bounds.top = bottom;
- bounds.bottom = bottom + dividerHeight;
- drawDivider(canvas, bounds, i);
+ if (bottom < listBottom) {
+ if ((areAllItemsSelectable ||
+ (adapter.isEnabled(first + i) && (i == count - 1 ||
+ adapter.isEnabled(first + i + 1))))) {
+ bounds.top = bottom;
+ bounds.bottom = bottom + dividerHeight;
+ drawDivider(canvas, bounds, i);
+ } else if (isOpaque) {
+ bounds.top = bottom;
+ bounds.bottom = bottom + dividerHeight;
+ canvas.drawRect(bounds, paint);
+ }
}
}
}
@@ -2844,16 +2889,22 @@
View child = getChildAt(i);
top = child.getTop();
// Don't draw dividers next to items that are not enabled
- if (top > listTop && (areAllItemsSelectable ||
- (adapter.isEnabled(first + i) && (i == count - 1 ||
- adapter.isEnabled(first + i + 1))))) {
- bounds.top = top - dividerHeight;
- bounds.bottom = top;
- // Give the method the child ABOVE the divider, so we
- // subtract one from our child
- // position. Give -1 when there is no child above the
- // divider.
- drawDivider(canvas, bounds, i - 1);
+ if (top > listTop) {
+ if ((areAllItemsSelectable ||
+ (adapter.isEnabled(first + i) && (i == count - 1 ||
+ adapter.isEnabled(first + i + 1))))) {
+ bounds.top = top - dividerHeight;
+ bounds.bottom = top;
+ // Give the method the child ABOVE the divider, so we
+ // subtract one from our child
+ // position. Give -1 when there is no child above the
+ // divider.
+ drawDivider(canvas, bounds, i - 1);
+ } else if (isOpaque) {
+ bounds.top = top - dividerHeight;
+ bounds.bottom = top;
+ canvas.drawRect(bounds, paint);
+ }
}
}
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index acd25ee..975277b 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -18,6 +18,8 @@
import com.android.internal.R;
+import android.content.Context;
+import android.content.res.TypedArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -33,8 +35,6 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.IBinder;
-import android.content.Context;
-import android.content.res.TypedArray;
import android.util.AttributeSet;
import java.lang.ref.WeakReference;
@@ -73,8 +73,8 @@
*/
public static final int INPUT_METHOD_NOT_NEEDED = 2;
- private final Context mContext;
- private final WindowManager mWindowManager;
+ private Context mContext;
+ private WindowManager mWindowManager;
private boolean mIsShowing;
private boolean mIsDropdown;
@@ -159,8 +159,7 @@
*/
public PopupWindow(Context context, AttributeSet attrs, int defStyle) {
mContext = context;
- mWindowManager = (WindowManager)context.getSystemService(
- Context.WINDOW_SERVICE);
+ mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
TypedArray a =
context.obtainStyledAttributes(
@@ -273,11 +272,11 @@
* @param height the popup's height
* @param focusable true if the popup can be focused, false otherwise
*/
- public PopupWindow(View contentView, int width, int height,
- boolean focusable) {
- mContext = contentView.getContext();
- mWindowManager = (WindowManager)mContext.getSystemService(
- Context.WINDOW_SERVICE);
+ public PopupWindow(View contentView, int width, int height, boolean focusable) {
+ if (contentView != null) {
+ mContext = contentView.getContext();
+ mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ }
setContentView(contentView);
setWidth(width);
setHeight(height);
@@ -374,6 +373,14 @@
}
mContentView = contentView;
+
+ if (mContext == null) {
+ mContext = mContentView.getContext();
+ }
+
+ if (mWindowManager == null) {
+ mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ }
}
/**
@@ -748,6 +755,11 @@
* @param p the layout parameters of the popup's content view
*/
private void preparePopup(WindowManager.LayoutParams p) {
+ if (mContentView == null || mContext == null || mWindowManager == null) {
+ throw new IllegalStateException("You must specify a valid content view by "
+ + "calling setContentView() before attempting to show the popup.");
+ }
+
if (mBackground != null) {
final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
int height = ViewGroup.LayoutParams.FILL_PARENT;
@@ -1005,6 +1017,7 @@
unregisterForScrollChanged();
mWindowManager.removeView(mPopupView);
+
if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
((ViewGroup) mPopupView).removeView(mContentView);
}
@@ -1304,7 +1317,16 @@
return super.onTouchEvent(event);
}
}
-
+
+ @Override
+ public void sendAccessibilityEvent(int eventType) {
+ // clinets are interested in the content not the container, make it event source
+ if (mContentView != null) {
+ mContentView.sendAccessibilityEvent(eventType);
+ } else {
+ super.sendAccessibilityEvent(eventType);
+ }
+ }
}
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index edbb3db..ef240e0 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -16,17 +16,22 @@
package android.widget;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Gravity;
-import android.view.ViewDebug;
-import android.widget.RemoteViews.RemoteView;
-import android.graphics.Rect;
import com.android.internal.R;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.RemoteViews.RemoteView;
+
+import java.util.Comparator;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* A Layout where the positions of the children can be described in relation to each other or to the
@@ -137,6 +142,8 @@
private final Rect mSelfBounds = new Rect();
private int mIgnoreGravity;
+ private static SortedSet<View> mTopToBottomLeftToRightSet = null;
+
public RelativeLayout(Context context) {
super(context);
}
@@ -782,6 +789,57 @@
return new LayoutParams(p);
}
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ if (mTopToBottomLeftToRightSet == null) {
+ mTopToBottomLeftToRightSet = new TreeSet<View>(new TopToBottomLeftToRightComparator());
+ }
+
+ // sort children top-to-bottom and left-to-right
+ for (int i = 0, count = getChildCount(); i < count; i++) {
+ mTopToBottomLeftToRightSet.add(getChildAt(i));
+ }
+
+ for (View view : mTopToBottomLeftToRightSet) {
+ if (view.dispatchPopulateAccessibilityEvent(event)) {
+ mTopToBottomLeftToRightSet.clear();
+ return true;
+ }
+ }
+
+ mTopToBottomLeftToRightSet.clear();
+ return false;
+ }
+
+ /**
+ * Compares two views in left-to-right and top-to-bottom fashion.
+ */
+ private class TopToBottomLeftToRightComparator implements Comparator<View> {
+ public int compare(View first, View second) {
+ // top - bottom
+ int topDifference = first.getTop() - second.getTop();
+ if (topDifference != 0) {
+ return topDifference;
+ }
+ // left - right
+ int leftDifference = first.getLeft() - second.getLeft();
+ if (leftDifference != 0) {
+ return leftDifference;
+ }
+ // break tie by height
+ int heightDiference = first.getHeight() - second.getHeight();
+ if (heightDiference != 0) {
+ return heightDiference;
+ }
+ // break tie by width
+ int widthDiference = first.getWidth() - second.getWidth();
+ if (widthDiference != 0) {
+ return widthDiference;
+ }
+ return 0;
+ }
+ }
+
/**
* Per-child layout information associated with RelativeLayout.
*
diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java
index 92561ed..f706744 100644
--- a/core/java/android/widget/SlidingDrawer.java
+++ b/core/java/android/widget/SlidingDrawer.java
@@ -16,21 +16,22 @@
package android.widget;
-import android.view.ViewGroup;
-import android.view.View;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.SoundEffectConstants;
+import android.R;
import android.content.Context;
import android.content.res.TypedArray;
-import android.util.AttributeSet;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
-import android.graphics.Bitmap;
-import android.os.SystemClock;
import android.os.Handler;
import android.os.Message;
-import android.R;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
/**
* SlidingDrawer hides content out of the screen and allows the user to drag a handle
@@ -746,6 +747,8 @@
openDrawer();
invalidate();
requestLayout();
+
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
/**
@@ -777,6 +780,7 @@
scrollListener.onScrollStarted();
}
animateClose(mVertical ? mHandle.getTop() : mHandle.getLeft());
+
if (scrollListener != null) {
scrollListener.onScrollEnded();
}
@@ -798,6 +802,9 @@
scrollListener.onScrollStarted();
}
animateOpen(mVertical ? mHandle.getTop() : mHandle.getLeft());
+
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
if (scrollListener != null) {
scrollListener.onScrollEnded();
}
@@ -827,6 +834,7 @@
}
mExpanded = true;
+
if (mOnDrawerOpenListener != null) {
mOnDrawerOpenListener.onDrawerOpened();
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index c6b01876..219afec 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,6 +16,11 @@
package android.widget;
+import com.android.internal.util.FastMath;
+import com.android.internal.widget.EditableInputConnection;
+
+import org.xmlpull.v1.XmlPullParserException;
+
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
@@ -31,17 +36,17 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ResultReceiver;
import android.os.SystemClock;
-import android.os.Message;
import android.text.BoringLayout;
+import android.text.ClipboardManager;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.GetChars;
import android.text.GraphicsOperations;
-import android.text.ClipboardManager;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Layout;
@@ -49,9 +54,9 @@
import android.text.Selection;
import android.text.SpanWatcher;
import android.text.Spannable;
+import android.text.SpannableString;
import android.text.Spanned;
import android.text.SpannedString;
-import android.text.SpannableString;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
@@ -64,19 +69,18 @@
import android.text.method.LinkMovementMethod;
import android.text.method.MetaKeyKeyListener;
import android.text.method.MovementMethod;
-import android.text.method.TimeKeyListener;
-
import android.text.method.PasswordTransformationMethod;
import android.text.method.SingleLineTransformationMethod;
import android.text.method.TextKeyListener;
+import android.text.method.TimeKeyListener;
import android.text.method.TransformationMethod;
import android.text.style.ParagraphStyle;
import android.text.style.URLSpan;
import android.text.style.UpdateAppearance;
import android.text.util.Linkify;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.FloatMath;
+import android.util.Log;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.Gravity;
@@ -89,25 +93,22 @@
import android.view.ViewRoot;
import android.view.ViewTreeObserver;
import android.view.ViewGroup.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.EditorInfo;
import android.widget.RemoteViews.RemoteView;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import com.android.internal.util.FastMath;
-import com.android.internal.widget.EditableInputConnection;
-
-import org.xmlpull.v1.XmlPullParserException;
-
/**
* Displays text to the user and optionally allows them to edit it. A TextView
* is a complete text editor, however the basic class is configured to not
@@ -4434,29 +4435,31 @@
boolean reportExtractedText() {
final InputMethodState ims = mInputMethodState;
- final boolean contentChanged = ims.mContentChanged;
- if (ims != null && (contentChanged || ims.mSelectionModeChanged)) {
- ims.mContentChanged = false;
- ims.mSelectionModeChanged = false;
- final ExtractedTextRequest req = mInputMethodState.mExtracting;
- if (req != null) {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- if (DEBUG_EXTRACT) Log.v(TAG, "Retrieving extracted start="
- + ims.mChangedStart + " end=" + ims.mChangedEnd
- + " delta=" + ims.mChangedDelta);
- if (ims.mChangedStart < 0 && !contentChanged) {
- ims.mChangedStart = EXTRACT_NOTHING;
- }
- if (extractTextInternal(req, ims.mChangedStart, ims.mChangedEnd,
- ims.mChangedDelta, ims.mTmpExtracted)) {
- if (DEBUG_EXTRACT) Log.v(TAG, "Reporting extracted start="
- + ims.mTmpExtracted.partialStartOffset
- + " end=" + ims.mTmpExtracted.partialEndOffset
- + ": " + ims.mTmpExtracted.text);
- imm.updateExtractedText(this, req.token,
- mInputMethodState.mTmpExtracted);
- return true;
+ if (ims != null) {
+ final boolean contentChanged = ims.mContentChanged;
+ if (contentChanged || ims.mSelectionModeChanged) {
+ ims.mContentChanged = false;
+ ims.mSelectionModeChanged = false;
+ final ExtractedTextRequest req = mInputMethodState.mExtracting;
+ if (req != null) {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ if (DEBUG_EXTRACT) Log.v(TAG, "Retrieving extracted start="
+ + ims.mChangedStart + " end=" + ims.mChangedEnd
+ + " delta=" + ims.mChangedDelta);
+ if (ims.mChangedStart < 0 && !contentChanged) {
+ ims.mChangedStart = EXTRACT_NOTHING;
+ }
+ if (extractTextInternal(req, ims.mChangedStart, ims.mChangedEnd,
+ ims.mChangedDelta, ims.mTmpExtracted)) {
+ if (DEBUG_EXTRACT) Log.v(TAG, "Reporting extracted start="
+ + ims.mTmpExtracted.partialStartOffset
+ + " end=" + ims.mTmpExtracted.partialEndOffset
+ + ": " + ims.mTmpExtracted.text);
+ imm.updateExtractedText(this, req.token,
+ mInputMethodState.mTmpExtracted);
+ return true;
+ }
}
}
}
@@ -6127,10 +6130,18 @@
private class ChangeWatcher
implements TextWatcher, SpanWatcher {
+
+ private CharSequence mBeforeText;
+
public void beforeTextChanged(CharSequence buffer, int start,
int before, int after) {
if (DEBUG_EXTRACT) Log.v(TAG, "beforeTextChanged start=" + start
+ " before=" + before + " after=" + after + ": " + buffer);
+
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ mBeforeText = buffer.toString();
+ }
+
TextView.this.sendBeforeTextChanged(buffer, start, before, after);
}
@@ -6139,6 +6150,13 @@
if (DEBUG_EXTRACT) Log.v(TAG, "onTextChanged start=" + start
+ " before=" + before + " after=" + after + ": " + buffer);
TextView.this.handleTextChanged(buffer, start, before, after);
+
+ if (AccessibilityManager.getInstance(mContext).isEnabled() &&
+ (isFocused() || isSelected() &&
+ isShown())) {
+ sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
+ mBeforeText = null;
+ }
}
public void afterTextChanged(Editable buffer) {
@@ -6774,6 +6792,40 @@
}
@Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ boolean isPassword =
+ (mInputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION)) ==
+ (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
+
+ if (!isPassword) {
+ CharSequence text = getText();
+ if (TextUtils.isEmpty(text)) {
+ text = getHint();
+ }
+ if (!TextUtils.isEmpty(text)) {
+ if (text.length() > AccessibilityEvent.MAX_TEXT_LENGTH) {
+ text = text.subSequence(0, AccessibilityEvent.MAX_TEXT_LENGTH + 1);
+ }
+ event.getText().add(text);
+ }
+ } else {
+ event.setPassword(isPassword);
+ }
+ return false;
+ }
+
+ void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
+ int fromIndex, int removedCount, int addedCount) {
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+ event.setFromIndex(fromIndex);
+ event.setRemovedCount(removedCount);
+ event.setAddedCount(addedCount);
+ event.setBeforeText(beforeText);
+ sendAccessibilityEventUnchecked(event);
+ }
+
+ @Override
protected void onCreateContextMenu(ContextMenu menu) {
super.onCreateContextMenu(menu);
boolean added = false;
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index ff74787..670692f 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -21,8 +21,8 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
-import android.os.RemoteException;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.view.Gravity;
@@ -278,7 +278,7 @@
}
tv.setText(s);
}
-
+
// =======================================================================================
// All the gunk below is the interaction with the Notification Service, which handles
// the proper ordering of these system-wide.
@@ -373,6 +373,7 @@
TAG, "REMOVE! " + mView + " in " + this);
mWM.removeView(mView);
}
+
mView = null;
}
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 9ce532c..e1ff2a5 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -45,6 +45,8 @@
void noteFullWifiLockReleased(int uid);
void noteScanWifiLockAcquired(int uid);
void noteScanWifiLockReleased(int uid);
+ void noteWifiMulticastEnabled(int uid);
+ void noteWifiMulticastDisabled(int uid);
void setOnBattery(boolean onBattery, int level);
void recordCurrentLevel(int level);
long getAwakeTimeBattery();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 1218fe3..e8356a2 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1115,7 +1115,21 @@
u.noteScanWifiLockReleasedLocked();
}
}
-
+
+ public void noteWifiMulticastEnabledLocked(int uid) {
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteWifiMulticastEnabledLocked();
+ }
+ }
+
+ public void noteWifiMulticastDisabledLocked(int uid) {
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteWifiMulticastDisabledLocked();
+ }
+ }
+
@Override public long getScreenOnTime(long batteryRealtime, int which) {
return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
@@ -1200,7 +1214,10 @@
boolean mScanWifiLockOut;
StopwatchTimer mScanWifiLockTimer;
-
+
+ boolean mWifiMulticastEnabled;
+ StopwatchTimer mWifiMulticastTimer;
+
Counter[] mUserActivityCounters;
/**
@@ -1228,6 +1245,8 @@
mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables);
mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables);
mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
+ mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
+ null, mUnpluggables);
}
@Override
@@ -1334,7 +1353,23 @@
mScanWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
}
}
-
+
+ @Override
+ public void noteWifiMulticastEnabledLocked() {
+ if (!mWifiMulticastEnabled) {
+ mWifiMulticastEnabled = true;
+ mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
+ @Override
+ public void noteWifiMulticastDisabledLocked() {
+ if (mWifiMulticastEnabled) {
+ mWifiMulticastEnabled = false;
+ mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
@Override
public long getWifiTurnedOnTime(long batteryRealtime, int which) {
return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
@@ -1349,7 +1384,13 @@
public long getScanWifiLockTime(long batteryRealtime, int which) {
return mScanWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
}
-
+
+ @Override
+ public long getWifiMulticastTime(long batteryRealtime, int which) {
+ return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
+ which);
+ }
+
@Override
public void noteUserActivityLocked(int type) {
if (mUserActivityCounters == null) {
@@ -1423,6 +1464,7 @@
mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
+ mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
if (mUserActivityCounters == null) {
out.writeInt(0);
} else {
@@ -1482,6 +1524,9 @@
mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
mScanWifiLockOut = false;
mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
+ mWifiMulticastEnabled = false;
+ mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
+ null, mUnpluggables, in);
if (in.readInt() == 0) {
mUserActivityCounters = null;
} else {
@@ -2709,7 +2754,9 @@
u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
u.mScanWifiLockOut = false;
u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
-
+ u.mWifiMulticastEnabled = false;
+ u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
+
if (in.readInt() != 0) {
if (u.mUserActivityCounters == null) {
u.initUserActivityLocked();
@@ -2842,6 +2889,7 @@
u.mWifiTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
u.mScanWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
if (u.mUserActivityCounters == null) {
out.writeInt(0);
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
index 17f5c7c..1b974ce 100644
--- a/core/java/com/android/internal/util/BitwiseOutputStream.java
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -17,7 +17,7 @@
package com.android.internal.util;
/**
- * An object that rovides bitwise incremental write access to a byte array.
+ * An object that provides bitwise incremental write access to a byte array.
*
* This is useful, for example, when writing a series of fields that
* may not be aligned on byte boundaries.
diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java
index 6034a1e..b81c2b3 100644
--- a/core/java/com/android/internal/view/menu/IconMenuView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuView.java
@@ -498,19 +498,23 @@
@Override
protected void onDraw(Canvas canvas) {
- if (mHorizontalDivider != null) {
+ Drawable drawable = mHorizontalDivider;
+ if (drawable != null) {
// If we have a horizontal divider to draw, draw it at the remembered positions
- for (int i = mHorizontalDividerRects.size() - 1; i >= 0; i--) {
- mHorizontalDivider.setBounds(mHorizontalDividerRects.get(i));
- mHorizontalDivider.draw(canvas);
+ final ArrayList<Rect> rects = mHorizontalDividerRects;
+ for (int i = rects.size() - 1; i >= 0; i--) {
+ drawable.setBounds(rects.get(i));
+ drawable.draw(canvas);
}
}
-
- if (mVerticalDivider != null) {
+
+ drawable = mVerticalDivider;
+ if (drawable != null) {
// If we have a vertical divider to draw, draw it at the remembered positions
- for (int i = mVerticalDividerRects.size() - 1; i >= 0; i--) {
- mVerticalDivider.setBounds(mVerticalDividerRects.get(i));
- mVerticalDivider.draw(canvas);
+ final ArrayList<Rect> rects = mVerticalDividerRects;
+ for (int i = rects.size() - 1; i >= 0; i--) {
+ drawable.setBounds(rects.get(i));
+ drawable.draw(canvas);
}
}
}
@@ -520,14 +524,12 @@
}
@Override
- public LayoutParams generateLayoutParams(AttributeSet attrs)
- {
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new IconMenuView.LayoutParams(getContext(), attrs);
}
@Override
- protected boolean checkLayoutParams(ViewGroup.LayoutParams p)
- {
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
// Override to allow type-checking of LayoutParams.
return p instanceof IconMenuView.LayoutParams;
}
diff --git a/core/java/com/google/android/net/GoogleHttpClient.java b/core/java/com/google/android/net/GoogleHttpClient.java
index 871c925..25d0122 100644
--- a/core/java/com/google/android/net/GoogleHttpClient.java
+++ b/core/java/com/google/android/net/GoogleHttpClient.java
@@ -37,6 +37,10 @@
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.LayeredSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.impl.client.EntityEnclosingRequestWrapper;
import org.apache.http.impl.client.RequestWrapper;
import org.apache.http.params.HttpParams;
@@ -44,6 +48,8 @@
import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
@@ -66,25 +72,22 @@
private final AndroidHttpClient mClient;
private final ContentResolver mResolver;
- private final String mUserAgent;
+ private final String mAppName, mUserAgent;
+ private final ThreadLocal mConnectionAllocated = new ThreadLocal<Boolean>();
/**
- * Create an HTTP client. Normally one client is shared throughout an app.
- * @param resolver to use for accessing URL rewriting rules.
- * @param userAgent to report in your HTTP requests.
- * @deprecated Use {@link #GoogleHttpClient(android.content.ContentResolver, String, boolean)}
+ * Create an HTTP client without SSL session persistence.
+ * @deprecated Use {@link #GoogleHttpClient(android.content.Context, String, boolean)}
*/
public GoogleHttpClient(ContentResolver resolver, String userAgent) {
mClient = AndroidHttpClient.newInstance(userAgent);
mResolver = resolver;
- mUserAgent = userAgent;
+ mUserAgent = mAppName = userAgent;
}
/**
- * GoogleHttpClient(Context, String, boolean) - without SSL session
- * persistence.
- *
- * @deprecated use Context instead of ContentResolver.
+ * Create an HTTP client without SSL session persistence.
+ * @deprecated Use {@link #GoogleHttpClient(android.content.Context, String, boolean)}
*/
public GoogleHttpClient(ContentResolver resolver, String appAndVersion,
boolean gzipCapable) {
@@ -111,21 +114,70 @@
* headers. Needed because Google servers require gzip in the User-Agent
* in order to return gzip'd content.
*/
- public GoogleHttpClient(Context context, String appAndVersion,
- boolean gzipCapable) {
- this(context.getContentResolver(), SSLClientSessionCacheFactory.getCache(context),
+ public GoogleHttpClient(Context context, String appAndVersion, boolean gzipCapable) {
+ this(context.getContentResolver(),
+ SSLClientSessionCacheFactory.getCache(context),
appAndVersion, gzipCapable);
}
- private GoogleHttpClient(ContentResolver resolver, SSLClientSessionCache cache,
+ private GoogleHttpClient(ContentResolver resolver,
+ SSLClientSessionCache cache,
String appAndVersion, boolean gzipCapable) {
String userAgent = appAndVersion + " (" + Build.DEVICE + " " + Build.ID + ")";
if (gzipCapable) {
userAgent = userAgent + "; gzip";
}
+
mClient = AndroidHttpClient.newInstance(userAgent, cache);
mResolver = resolver;
+ mAppName = appAndVersion;
mUserAgent = userAgent;
+
+ // Wrap all the socket factories with the appropriate wrapper. (Apache
+ // HTTP, curse its black and stupid heart, inspects the SocketFactory to
+ // see if it's a LayeredSocketFactory, so we need two wrapper classes.)
+ SchemeRegistry registry = getConnectionManager().getSchemeRegistry();
+ for (String name : registry.getSchemeNames()) {
+ Scheme scheme = registry.unregister(name);
+ SocketFactory sf = scheme.getSocketFactory();
+ if (sf instanceof LayeredSocketFactory) {
+ sf = new WrappedLayeredSocketFactory((LayeredSocketFactory) sf);
+ } else {
+ sf = new WrappedSocketFactory(sf);
+ }
+ registry.register(new Scheme(name, sf, scheme.getDefaultPort()));
+ }
+ }
+
+ /**
+ * Delegating wrapper for SocketFactory records when sockets are connected.
+ * We use this to know whether a connection was created vs reused, to
+ * gather per-app statistics about connection reuse rates.
+ */
+ private class WrappedSocketFactory implements SocketFactory {
+ private SocketFactory mDelegate;
+ private WrappedSocketFactory(SocketFactory delegate) { mDelegate = delegate; }
+ public final Socket createSocket() throws IOException { return mDelegate.createSocket(); }
+ public final boolean isSecure(Socket s) { return mDelegate.isSecure(s); }
+
+ public final Socket connectSocket(
+ Socket s, String h, int p,
+ InetAddress la, int lp, HttpParams params) throws IOException {
+ mConnectionAllocated.set(Boolean.TRUE);
+ return mDelegate.connectSocket(s, h, p, la, lp, params);
+ }
+ }
+
+ /** Like WrappedSocketFactory, but for the LayeredSocketFactory subclass. */
+ private class WrappedLayeredSocketFactory
+ extends WrappedSocketFactory implements LayeredSocketFactory {
+ private LayeredSocketFactory mDelegate;
+ private WrappedLayeredSocketFactory(LayeredSocketFactory sf) { super(sf); mDelegate = sf; }
+
+ public final Socket createSocket(Socket s, String host, int port, boolean autoClose)
+ throws IOException {
+ return mDelegate.createSocket(s, host, port, autoClose);
+ }
}
/**
@@ -140,24 +192,21 @@
public HttpResponse executeWithoutRewriting(
HttpUriRequest request, HttpContext context)
throws IOException {
- String code = "Error";
+ int code = -1;
long start = SystemClock.elapsedRealtime();
try {
HttpResponse response;
- // TODO: if we're logging network stats, and if the apache library is configured
- // to follow redirects, count each redirect as an additional round trip.
+ mConnectionAllocated.set(null);
- // see if we're logging network stats.
- boolean logNetworkStats = NetworkStatsEntity.shouldLogNetworkStats();
+ if (NetworkStatsEntity.shouldLogNetworkStats()) {
+ // TODO: if we're logging network stats, and if the apache library is configured
+ // to follow redirects, count each redirect as an additional round trip.
- if (logNetworkStats) {
int uid = android.os.Process.myUid();
long startTx = NetStat.getUidTxBytes(uid);
long startRx = NetStat.getUidRxBytes(uid);
response = mClient.execute(request, context);
- code = Integer.toString(response.getStatusLine().getStatusCode());
-
HttpEntity origEntity = response == null ? null : response.getEntity();
if (origEntity != null) {
// yeah, we compute the same thing below. we do need to compute this here
@@ -165,30 +214,37 @@
long now = SystemClock.elapsedRealtime();
long elapsed = now - start;
NetworkStatsEntity entity = new NetworkStatsEntity(origEntity,
- mUserAgent, uid, startTx, startRx,
+ mAppName, uid, startTx, startRx,
elapsed /* response latency */, now /* processing start time */);
response.setEntity(entity);
}
} else {
response = mClient.execute(request, context);
- code = Integer.toString(response.getStatusLine().getStatusCode());
}
+ code = response.getStatusLine().getStatusCode();
return response;
- } catch (IOException e) {
- code = "IOException";
- throw e;
} finally {
// Record some statistics to the checkin service about the outcome.
// Note that this is only describing execute(), not body download.
try {
long elapsed = SystemClock.elapsedRealtime() - start;
ContentValues values = new ContentValues();
- values.put(Checkin.Stats.TAG,
- Checkin.Stats.Tag.HTTP_STATUS + ":" +
- mUserAgent + ":" + code);
values.put(Checkin.Stats.COUNT, 1);
values.put(Checkin.Stats.SUM, elapsed / 1000.0);
+
+ values.put(Checkin.Stats.TAG, Checkin.Stats.Tag.HTTP_REQUEST + ":" + mAppName);
+ mResolver.insert(Checkin.Stats.CONTENT_URI, values);
+
+ // No sockets and no exceptions means we successfully reused a connection
+ if (mConnectionAllocated.get() == null && code >= 0) {
+ values.put(Checkin.Stats.TAG, Checkin.Stats.Tag.HTTP_REUSED + ":" + mAppName);
+ mResolver.insert(Checkin.Stats.CONTENT_URI, values);
+ }
+
+ String status = code < 0 ? "IOException" : Integer.toString(code);
+ values.put(Checkin.Stats.TAG,
+ Checkin.Stats.Tag.HTTP_STATUS + ":" + mAppName + ":" + status);
mResolver.insert(Checkin.Stats.CONTENT_URI, values);
} catch (Exception e) {
Log.e(TAG, "Error recording stats", e);
diff --git a/core/jni/android_backup_FileBackupHelper.cpp b/core/jni/android_backup_FileBackupHelper.cpp
index e8d60a0..c6de3a5 100644
--- a/core/jni/android_backup_FileBackupHelper.cpp
+++ b/core/jni/android_backup_FileBackupHelper.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "FileBackupHelper_native"
+#include <utils/Log.h>
+
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
@@ -22,29 +25,29 @@
namespace android
{
-static jfieldID s_descriptorField;
+static jfieldID s_descriptorField = 0;
static int
-performBackup_native(JNIEnv* env, jstring basePath,
- jobject oldSnapshot, jobject newSnapshot,
- jobject data, jobjectArray files)
+performBackup_native(JNIEnv* env, jobject clazz, jstring basePath, jobject oldState, jobject data,
+ jobject newState, jobjectArray files)
{
int err;
// all parameters have already been checked against null
-
- int oldSnapshotFD = env->GetIntField(oldSnapshot, s_descriptorField);
- int newSnapshotFD = env->GetIntField(newSnapshot, s_descriptorField);
+ LOGD("oldState=%p newState=%p data=%p\n", oldState, newState, data);
+ int oldStateFD = oldState != NULL ? env->GetIntField(oldState, s_descriptorField) : -1;
+ int newStateFD = env->GetIntField(newState, s_descriptorField);
int dataFD = env->GetIntField(data, s_descriptorField);
char const* basePathUTF = env->GetStringUTFChars(basePath, NULL);
+ LOGD("basePathUTF=\"%s\"\n", basePathUTF);
const int fileCount = env->GetArrayLength(files);
char const** filesUTF = (char const**)malloc(sizeof(char*)*fileCount);
for (int i=0; i<fileCount; i++) {
filesUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(files, i), NULL);
}
- err = back_up_files(oldSnapshotFD, newSnapshotFD, dataFD, basePathUTF, filesUTF, fileCount);
+ err = back_up_files(oldStateFD, dataFD, newStateFD, basePathUTF, filesUTF, fileCount);
for (int i=0; i<fileCount; i++) {
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(files, i), filesUTF[i]);
@@ -64,6 +67,8 @@
int register_android_backup_FileBackupHelper(JNIEnv* env)
{
+ LOGD("register_android_backup_FileBackupHelper");
+
jclass clazz;
clazz = env->FindClass("java/io/FileDescriptor");
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 482d8eb..2685d75 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -133,6 +133,19 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
static int
getNumCompressedTextureFormats() {
int numCompressedTextureFormats = 0;
@@ -305,9 +318,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -2779,9 +2791,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -3034,9 +3045,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -3392,9 +3402,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index 923e1aa..7c208e9 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -44,6 +44,7 @@
static jfieldID g_shortMonthsField = 0;
static jfieldID g_longMonthsField = 0;
+static jfieldID g_longStandaloneMonthsField = 0;
static jfieldID g_shortWeekdaysField = 0;
static jfieldID g_longWeekdaysField = 0;
static jfieldID g_timeOnlyFormatField = 0;
@@ -193,6 +194,7 @@
static jobject js_locale_previous = NULL;
static struct strftime_locale locale;
static jstring js_mon[12], js_month[12], js_wday[7], js_weekday[7];
+ static jstring js_standalone_month[12];
static jstring js_X_fmt, js_x_fmt, js_c_fmt, js_am, js_pm, js_date_fmt;
Time t;
@@ -206,8 +208,10 @@
for (int i = 0; i < 12; i++) {
env->ReleaseStringUTFChars(js_mon[i], locale.mon[i]);
env->ReleaseStringUTFChars(js_month[i], locale.month[i]);
+ env->ReleaseStringUTFChars(js_standalone_month[i], locale.standalone_month[i]);
env->DeleteGlobalRef(js_mon[i]);
env->DeleteGlobalRef(js_month[i]);
+ env->DeleteGlobalRef(js_standalone_month[i]);
}
for (int i = 0; i < 7; i++) {
@@ -245,6 +249,12 @@
locale.month[i] = env->GetStringUTFChars(js_month[i], NULL);
}
+ ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_longStandaloneMonthsField);
+ for (int i = 0; i < 12; i++) {
+ js_standalone_month[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i));
+ locale.standalone_month[i] = env->GetStringUTFChars(js_standalone_month[i], NULL);
+ }
+
ja = (jobjectArray) env->GetStaticObjectField(timeClass, g_shortWeekdaysField);
for (int i = 0; i < 7; i++) {
js_wday[i] = (jstring) env->NewGlobalRef(env->GetObjectArrayElement(ja, i));
@@ -639,6 +649,7 @@
g_shortMonthsField = env->GetStaticFieldID(timeClass, "sShortMonths", "[Ljava/lang/String;");
g_longMonthsField = env->GetStaticFieldID(timeClass, "sLongMonths", "[Ljava/lang/String;");
+ g_longStandaloneMonthsField = env->GetStaticFieldID(timeClass, "sLongStandaloneMonths", "[Ljava/lang/String;");
g_shortWeekdaysField = env->GetStaticFieldID(timeClass, "sShortWeekdays", "[Ljava/lang/String;");
g_longWeekdaysField = env->GetStaticFieldID(timeClass, "sLongWeekdays", "[Ljava/lang/String;");
g_timeOnlyFormatField = env->GetStaticFieldID(timeClass, "sTimeOnlyFormat", "Ljava/lang/String;");
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index 11822e0..15e3a81 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -133,6 +133,19 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
static int
getNumCompressedTextureFormats() {
int numCompressedTextureFormats = 0;
@@ -305,9 +318,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -2779,9 +2791,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -3034,9 +3045,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
@@ -3392,9 +3402,8 @@
GLvoid *pointer = (GLvoid *) 0;
if (pointer_buf) {
- pointer = (GLvoid *) _env->GetDirectBufferAddress(pointer_buf);
+ pointer = (GLvoid *) getDirectBufferPointer(_env, pointer_buf);
if ( ! pointer ) {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
return;
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index bff6b9d..ca2db11 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -389,11 +389,11 @@
android:description="@string/permgroupdesc_storage" />
<!-- Allows an application to write to the SD card -->
- <permission android:name="android.permission.SDCARD_WRITE"
+ <permission android:name="android.permission.WRITE_SDCARD"
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_sdcardWrite"
android:description="@string/permdesc_sdcardWrite"
- android:protectionLevel="normal" />
+ android:protectionLevel="dangerous" />
<!-- ============================================ -->
<!-- Permissions for low-level system interaction -->
@@ -973,7 +973,7 @@
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:label="@string/permlab_bindGadget"
android:description="@string/permdesc_bindGadget"
- android:protectionLevel="signature" />
+ android:protectionLevel="signatureOrSystem" />
<!-- Allows applications to change the background data setting
@hide pending API council -->
diff --git a/core/res/res/drawable/btn_search_dialog_default.9.png b/core/res/res/drawable/btn_search_dialog_default.9.png
index ec39178..7275231 100644
--- a/core/res/res/drawable/btn_search_dialog_default.9.png
+++ b/core/res/res/drawable/btn_search_dialog_default.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_pressed.9.png b/core/res/res/drawable/btn_search_dialog_pressed.9.png
index 5f52fef..50a9209 100644
--- a/core/res/res/drawable/btn_search_dialog_pressed.9.png
+++ b/core/res/res/drawable/btn_search_dialog_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_selected.9.png b/core/res/res/drawable/btn_search_dialog_selected.9.png
index 9fc2fde..14b774a 100644
--- a/core/res/res/drawable/btn_search_dialog_selected.9.png
+++ b/core/res/res/drawable/btn_search_dialog_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice_default.9.png b/core/res/res/drawable/btn_search_dialog_voice_default.9.png
index 2a3366c..febf222 100644
--- a/core/res/res/drawable/btn_search_dialog_voice_default.9.png
+++ b/core/res/res/drawable/btn_search_dialog_voice_default.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png b/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png
index 57d7a74..70a200b 100644
--- a/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png
+++ b/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice_selected.9.png b/core/res/res/drawable/btn_search_dialog_voice_selected.9.png
index db3187e..6f2989f 100644
--- a/core/res/res/drawable/btn_search_dialog_voice_selected.9.png
+++ b/core/res/res/drawable/btn_search_dialog_voice_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_horizontal_bright.9.png b/core/res/res/drawable/divider_horizontal_bright.9.png
index 30c9b2b..144fc22 100644
--- a/core/res/res/drawable/divider_horizontal_bright.9.png
+++ b/core/res/res/drawable/divider_horizontal_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_horizontal_bright_opaque.9.png b/core/res/res/drawable/divider_horizontal_bright_opaque.9.png
new file mode 100644
index 0000000..30c9b2b
--- /dev/null
+++ b/core/res/res/drawable/divider_horizontal_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_horizontal_dark.9.png b/core/res/res/drawable/divider_horizontal_dark.9.png
index ce21acd..08838ca 100644
--- a/core/res/res/drawable/divider_horizontal_dark.9.png
+++ b/core/res/res/drawable/divider_horizontal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_horizontal_dark_opaque.9.png b/core/res/res/drawable/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..ce21acd
--- /dev/null
+++ b/core/res/res/drawable/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/values-ar-rEG/donottranslate-cldr.xml b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
new file mode 100644
index 0000000..1bbbdca
--- /dev/null
+++ b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">يناير</string>
+ <string name="month_long_standalone_february">فبراير</string>
+ <string name="month_long_standalone_march">مارس</string>
+ <string name="month_long_standalone_april">أبريل</string>
+ <string name="month_long_standalone_may">مايو</string>
+ <string name="month_long_standalone_june">يونيو</string>
+ <string name="month_long_standalone_july">يوليو</string>
+ <string name="month_long_standalone_august">أغسطس</string>
+ <string name="month_long_standalone_september">سبتمبر</string>
+ <string name="month_long_standalone_october">أكتوبر</string>
+ <string name="month_long_standalone_november">نوفمبر</string>
+ <string name="month_long_standalone_december">ديسمبر</string>
+
+ <string name="month_long_january">يناير</string>
+ <string name="month_long_february">فبراير</string>
+ <string name="month_long_march">مارس</string>
+ <string name="month_long_april">أبريل</string>
+ <string name="month_long_may">مايو</string>
+ <string name="month_long_june">يونيو</string>
+ <string name="month_long_july">يوليو</string>
+ <string name="month_long_august">أغسطس</string>
+ <string name="month_long_september">سبتمبر</string>
+ <string name="month_long_october">أكتوبر</string>
+ <string name="month_long_november">نوفمبر</string>
+ <string name="month_long_december">ديسمبر</string>
+
+ <string name="month_medium_january">يناير</string>
+ <string name="month_medium_february">فبراير</string>
+ <string name="month_medium_march">مارس</string>
+ <string name="month_medium_april">أبريل</string>
+ <string name="month_medium_may">مايو</string>
+ <string name="month_medium_june">يونيو</string>
+ <string name="month_medium_july">يوليو</string>
+ <string name="month_medium_august">أغسطس</string>
+ <string name="month_medium_september">سبتمبر</string>
+ <string name="month_medium_october">أكتوبر</string>
+ <string name="month_medium_november">نوفمبر</string>
+ <string name="month_medium_december">ديسمبر</string>
+
+ <string name="month_shortest_january">ي</string>
+ <string name="month_shortest_february">ف</string>
+ <string name="month_shortest_march">م</string>
+ <string name="month_shortest_april">أ</string>
+ <string name="month_shortest_may">و</string>
+ <string name="month_shortest_june">ن</string>
+ <string name="month_shortest_july">ل</string>
+ <string name="month_shortest_august">غ</string>
+ <string name="month_shortest_september">س</string>
+ <string name="month_shortest_october">ك</string>
+ <string name="month_shortest_november">ب</string>
+ <string name="month_shortest_december">د</string>
+
+ <string name="day_of_week_long_sunday">الأحد</string>
+ <string name="day_of_week_long_monday">الإثنين</string>
+ <string name="day_of_week_long_tuesday">الثلاثاء</string>
+ <string name="day_of_week_long_wednesday">الأربعاء</string>
+ <string name="day_of_week_long_thursday">الخميس</string>
+ <string name="day_of_week_long_friday">الجمعة</string>
+ <string name="day_of_week_long_saturday">السبت</string>
+
+ <string name="day_of_week_medium_sunday">أحد</string>
+ <string name="day_of_week_medium_monday">إثنين</string>
+ <string name="day_of_week_medium_tuesday">ثلاثاء</string>
+ <string name="day_of_week_medium_wednesday">أربعاء</string>
+ <string name="day_of_week_medium_thursday">خميس</string>
+ <string name="day_of_week_medium_friday">جمعة</string>
+ <string name="day_of_week_medium_saturday">سبت</string>
+
+ <string name="day_of_week_short_sunday">أحد</string>
+ <string name="day_of_week_short_monday">إثنين</string>
+ <string name="day_of_week_short_tuesday">ثلاثاء</string>
+ <string name="day_of_week_short_wednesday">أربعاء</string>
+ <string name="day_of_week_short_thursday">خميس</string>
+ <string name="day_of_week_short_friday">جمعة</string>
+ <string name="day_of_week_short_saturday">سبت</string>
+
+ <string name="day_of_week_shortest_sunday">ح</string>
+ <string name="day_of_week_shortest_monday">ن</string>
+ <string name="day_of_week_shortest_tuesday">ث</string>
+ <string name="day_of_week_shortest_wednesday">ر</string>
+ <string name="day_of_week_shortest_thursday">خ</string>
+ <string name="day_of_week_shortest_friday">ج</string>
+ <string name="day_of_week_shortest_saturday">س</string>
+
+ <string name="am">ص</string>
+ <string name="pm">م</string>
+ <string name="yesterday">أمس</string>
+ <string name="today">اليوم</string>
+ <string name="tomorrow">غدًا</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-e/%-m/%Y</string>
+ <string name="numeric_date_format">d/M/yyyy</string>
+ <string name="month_day_year">%-e %B، %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-bg-rBG/donottranslate-cldr.xml b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
new file mode 100644
index 0000000..608b3a7
--- /dev/null
+++ b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">януари</string>
+ <string name="month_long_standalone_february">февруари</string>
+ <string name="month_long_standalone_march">март</string>
+ <string name="month_long_standalone_april">април</string>
+ <string name="month_long_standalone_may">май</string>
+ <string name="month_long_standalone_june">юни</string>
+ <string name="month_long_standalone_july">юли</string>
+ <string name="month_long_standalone_august">август</string>
+ <string name="month_long_standalone_september">септември</string>
+ <string name="month_long_standalone_october">октомври</string>
+ <string name="month_long_standalone_november">ноември</string>
+ <string name="month_long_standalone_december">декември</string>
+
+ <string name="month_long_january">януари</string>
+ <string name="month_long_february">февруари</string>
+ <string name="month_long_march">март</string>
+ <string name="month_long_april">април</string>
+ <string name="month_long_may">май</string>
+ <string name="month_long_june">юни</string>
+ <string name="month_long_july">юли</string>
+ <string name="month_long_august">август</string>
+ <string name="month_long_september">септември</string>
+ <string name="month_long_october">октомври</string>
+ <string name="month_long_november">ноември</string>
+ <string name="month_long_december">декември</string>
+
+ <string name="month_medium_january">ян.</string>
+ <string name="month_medium_february">февр.</string>
+ <string name="month_medium_march">март</string>
+ <string name="month_medium_april">апр.</string>
+ <string name="month_medium_may">май</string>
+ <string name="month_medium_june">юни</string>
+ <string name="month_medium_july">юли</string>
+ <string name="month_medium_august">авг.</string>
+ <string name="month_medium_september">септ.</string>
+ <string name="month_medium_october">окт.</string>
+ <string name="month_medium_november">ноем.</string>
+ <string name="month_medium_december">дек.</string>
+
+ <string name="month_shortest_january">я</string>
+ <string name="month_shortest_february">ф</string>
+ <string name="month_shortest_march">м</string>
+ <string name="month_shortest_april">а</string>
+ <string name="month_shortest_may">м</string>
+ <string name="month_shortest_june">ю</string>
+ <string name="month_shortest_july">ю</string>
+ <string name="month_shortest_august">а</string>
+ <string name="month_shortest_september">с</string>
+ <string name="month_shortest_october">о</string>
+ <string name="month_shortest_november">н</string>
+ <string name="month_shortest_december">д</string>
+
+ <string name="day_of_week_long_sunday">неделя</string>
+ <string name="day_of_week_long_monday">понеделник</string>
+ <string name="day_of_week_long_tuesday">вторник</string>
+ <string name="day_of_week_long_wednesday">сряда</string>
+ <string name="day_of_week_long_thursday">четвъртък</string>
+ <string name="day_of_week_long_friday">петък</string>
+ <string name="day_of_week_long_saturday">събота</string>
+
+ <string name="day_of_week_medium_sunday">нд</string>
+ <string name="day_of_week_medium_monday">пн</string>
+ <string name="day_of_week_medium_tuesday">вт</string>
+ <string name="day_of_week_medium_wednesday">ср</string>
+ <string name="day_of_week_medium_thursday">чт</string>
+ <string name="day_of_week_medium_friday">пт</string>
+ <string name="day_of_week_medium_saturday">сб</string>
+
+ <string name="day_of_week_short_sunday">нд</string>
+ <string name="day_of_week_short_monday">пн</string>
+ <string name="day_of_week_short_tuesday">вт</string>
+ <string name="day_of_week_short_wednesday">ср</string>
+ <string name="day_of_week_short_thursday">чт</string>
+ <string name="day_of_week_short_friday">пт</string>
+ <string name="day_of_week_short_saturday">сб</string>
+
+ <string name="day_of_week_shortest_sunday">н</string>
+ <string name="day_of_week_shortest_monday">п</string>
+ <string name="day_of_week_shortest_tuesday">в</string>
+ <string name="day_of_week_shortest_wednesday">с</string>
+ <string name="day_of_week_shortest_thursday">ч</string>
+ <string name="day_of_week_shortest_friday">п</string>
+ <string name="day_of_week_shortest_saturday">с</string>
+
+ <string name="am">пр. об.</string>
+ <string name="pm">сл. об.</string>
+ <string name="yesterday">Вчера</string>
+ <string name="today">Днес</string>
+ <string name="tomorrow">Утре</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-ca-rES/donottranslate-cldr.xml b/core/res/res/values-ca-rES/donottranslate-cldr.xml
new file mode 100644
index 0000000..6ed2a88
--- /dev/null
+++ b/core/res/res/values-ca-rES/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">gener</string>
+ <string name="month_long_standalone_february">febrer</string>
+ <string name="month_long_standalone_march">març</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">maig</string>
+ <string name="month_long_standalone_june">juny</string>
+ <string name="month_long_standalone_july">juliol</string>
+ <string name="month_long_standalone_august">agost</string>
+ <string name="month_long_standalone_september">setembre</string>
+ <string name="month_long_standalone_october">octubre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">desembre</string>
+
+ <string name="month_long_january">gener</string>
+ <string name="month_long_february">febrer</string>
+ <string name="month_long_march">març</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">maig</string>
+ <string name="month_long_june">juny</string>
+ <string name="month_long_july">juliol</string>
+ <string name="month_long_august">agost</string>
+ <string name="month_long_september">setembre</string>
+ <string name="month_long_october">octubre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">desembre</string>
+
+ <string name="month_medium_january">gen.</string>
+ <string name="month_medium_february">febr.</string>
+ <string name="month_medium_march">març</string>
+ <string name="month_medium_april">abr.</string>
+ <string name="month_medium_may">maig</string>
+ <string name="month_medium_june">juny</string>
+ <string name="month_medium_july">jul.</string>
+ <string name="month_medium_august">ag.</string>
+ <string name="month_medium_september">set.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">des.</string>
+
+ <string name="month_shortest_january">g</string>
+ <string name="month_shortest_february">f</string>
+ <string name="month_shortest_march">m</string>
+ <string name="month_shortest_april">a</string>
+ <string name="month_shortest_may">m</string>
+ <string name="month_shortest_june">j</string>
+ <string name="month_shortest_july">j</string>
+ <string name="month_shortest_august">a</string>
+ <string name="month_shortest_september">s</string>
+ <string name="month_shortest_october">o</string>
+ <string name="month_shortest_november">n</string>
+ <string name="month_shortest_december">d</string>
+
+ <string name="day_of_week_long_sunday">diumenge</string>
+ <string name="day_of_week_long_monday">dilluns</string>
+ <string name="day_of_week_long_tuesday">dimarts</string>
+ <string name="day_of_week_long_wednesday">dimecres</string>
+ <string name="day_of_week_long_thursday">dijous</string>
+ <string name="day_of_week_long_friday">divendres</string>
+ <string name="day_of_week_long_saturday">dissabte</string>
+
+ <string name="day_of_week_medium_sunday">dg.</string>
+ <string name="day_of_week_medium_monday">dl.</string>
+ <string name="day_of_week_medium_tuesday">dt.</string>
+ <string name="day_of_week_medium_wednesday">dc.</string>
+ <string name="day_of_week_medium_thursday">dj.</string>
+ <string name="day_of_week_medium_friday">dv.</string>
+ <string name="day_of_week_medium_saturday">ds.</string>
+
+ <string name="day_of_week_short_sunday">dg.</string>
+ <string name="day_of_week_short_monday">dl.</string>
+ <string name="day_of_week_short_tuesday">dt.</string>
+ <string name="day_of_week_short_wednesday">dc.</string>
+ <string name="day_of_week_short_thursday">dj.</string>
+ <string name="day_of_week_short_friday">dv.</string>
+ <string name="day_of_week_short_saturday">ds.</string>
+
+ <string name="day_of_week_shortest_sunday">g</string>
+ <string name="day_of_week_shortest_monday">l</string>
+ <string name="day_of_week_shortest_tuesday">t</string>
+ <string name="day_of_week_shortest_wednesday">c</string>
+ <string name="day_of_week_shortest_thursday">j</string>
+ <string name="day_of_week_shortest_friday">v</string>
+ <string name="day_of_week_shortest_saturday">s</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">ahir</string>
+ <string name="today">avui</string>
+ <string name="tomorrow">demà</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B del %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
new file mode 100644
index 0000000..f477d56
--- /dev/null
+++ b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">leden</string>
+ <string name="month_long_standalone_february">únor</string>
+ <string name="month_long_standalone_march">březen</string>
+ <string name="month_long_standalone_april">duben</string>
+ <string name="month_long_standalone_may">květen</string>
+ <string name="month_long_standalone_june">červen</string>
+ <string name="month_long_standalone_july">červenec</string>
+ <string name="month_long_standalone_august">srpen</string>
+ <string name="month_long_standalone_september">září</string>
+ <string name="month_long_standalone_october">říjen</string>
+ <string name="month_long_standalone_november">listopad</string>
+ <string name="month_long_standalone_december">prosinec</string>
+
+ <string name="month_long_january">ledna</string>
+ <string name="month_long_february">února</string>
+ <string name="month_long_march">března</string>
+ <string name="month_long_april">dubna</string>
+ <string name="month_long_may">května</string>
+ <string name="month_long_june">června</string>
+ <string name="month_long_july">července</string>
+ <string name="month_long_august">srpna</string>
+ <string name="month_long_september">září</string>
+ <string name="month_long_october">října</string>
+ <string name="month_long_november">listopadu</string>
+ <string name="month_long_december">prosince</string>
+
+ <string name="month_medium_january">1</string>
+ <string name="month_medium_february">2</string>
+ <string name="month_medium_march">3</string>
+ <string name="month_medium_april">4</string>
+ <string name="month_medium_may">5</string>
+ <string name="month_medium_june">6</string>
+ <string name="month_medium_july">7</string>
+ <string name="month_medium_august">8</string>
+ <string name="month_medium_september">9</string>
+ <string name="month_medium_october">10</string>
+ <string name="month_medium_november">11</string>
+ <string name="month_medium_december">12</string>
+
+ <string name="month_shortest_january">l</string>
+ <string name="month_shortest_february">ú</string>
+ <string name="month_shortest_march">b</string>
+ <string name="month_shortest_april">d</string>
+ <string name="month_shortest_may">k</string>
+ <string name="month_shortest_june">č</string>
+ <string name="month_shortest_july">č</string>
+ <string name="month_shortest_august">s</string>
+ <string name="month_shortest_september">z</string>
+ <string name="month_shortest_october">ř</string>
+ <string name="month_shortest_november">l</string>
+ <string name="month_shortest_december">p</string>
+
+ <string name="day_of_week_long_sunday">neděle</string>
+ <string name="day_of_week_long_monday">pondělí</string>
+ <string name="day_of_week_long_tuesday">úterý</string>
+ <string name="day_of_week_long_wednesday">středa</string>
+ <string name="day_of_week_long_thursday">čtvrtek</string>
+ <string name="day_of_week_long_friday">pátek</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">ne</string>
+ <string name="day_of_week_medium_monday">po</string>
+ <string name="day_of_week_medium_tuesday">út</string>
+ <string name="day_of_week_medium_wednesday">st</string>
+ <string name="day_of_week_medium_thursday">čt</string>
+ <string name="day_of_week_medium_friday">pá</string>
+ <string name="day_of_week_medium_saturday">so</string>
+
+ <string name="day_of_week_short_sunday">ne</string>
+ <string name="day_of_week_short_monday">po</string>
+ <string name="day_of_week_short_tuesday">út</string>
+ <string name="day_of_week_short_wednesday">st</string>
+ <string name="day_of_week_short_thursday">čt</string>
+ <string name="day_of_week_short_friday">pá</string>
+ <string name="day_of_week_short_saturday">so</string>
+
+ <string name="day_of_week_shortest_sunday">N</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">Ú</string>
+ <string name="day_of_week_shortest_wednesday">S</string>
+ <string name="day_of_week_shortest_thursday">Č</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">dop.</string>
+ <string name="pm">odp.</string>
+ <string name="yesterday">Včera</string>
+ <string name="today">Dnes</string>
+ <string name="tomorrow">Zítra</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%-e.%-m.%Y</string>
+ <string name="numeric_date_format">d.M.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml
new file mode 100644
index 0000000..f477d56
--- /dev/null
+++ b/core/res/res/values-cs/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">leden</string>
+ <string name="month_long_standalone_february">únor</string>
+ <string name="month_long_standalone_march">březen</string>
+ <string name="month_long_standalone_april">duben</string>
+ <string name="month_long_standalone_may">květen</string>
+ <string name="month_long_standalone_june">červen</string>
+ <string name="month_long_standalone_july">červenec</string>
+ <string name="month_long_standalone_august">srpen</string>
+ <string name="month_long_standalone_september">září</string>
+ <string name="month_long_standalone_october">říjen</string>
+ <string name="month_long_standalone_november">listopad</string>
+ <string name="month_long_standalone_december">prosinec</string>
+
+ <string name="month_long_january">ledna</string>
+ <string name="month_long_february">února</string>
+ <string name="month_long_march">března</string>
+ <string name="month_long_april">dubna</string>
+ <string name="month_long_may">května</string>
+ <string name="month_long_june">června</string>
+ <string name="month_long_july">července</string>
+ <string name="month_long_august">srpna</string>
+ <string name="month_long_september">září</string>
+ <string name="month_long_october">října</string>
+ <string name="month_long_november">listopadu</string>
+ <string name="month_long_december">prosince</string>
+
+ <string name="month_medium_january">1</string>
+ <string name="month_medium_february">2</string>
+ <string name="month_medium_march">3</string>
+ <string name="month_medium_april">4</string>
+ <string name="month_medium_may">5</string>
+ <string name="month_medium_june">6</string>
+ <string name="month_medium_july">7</string>
+ <string name="month_medium_august">8</string>
+ <string name="month_medium_september">9</string>
+ <string name="month_medium_october">10</string>
+ <string name="month_medium_november">11</string>
+ <string name="month_medium_december">12</string>
+
+ <string name="month_shortest_january">l</string>
+ <string name="month_shortest_february">ú</string>
+ <string name="month_shortest_march">b</string>
+ <string name="month_shortest_april">d</string>
+ <string name="month_shortest_may">k</string>
+ <string name="month_shortest_june">č</string>
+ <string name="month_shortest_july">č</string>
+ <string name="month_shortest_august">s</string>
+ <string name="month_shortest_september">z</string>
+ <string name="month_shortest_october">ř</string>
+ <string name="month_shortest_november">l</string>
+ <string name="month_shortest_december">p</string>
+
+ <string name="day_of_week_long_sunday">neděle</string>
+ <string name="day_of_week_long_monday">pondělí</string>
+ <string name="day_of_week_long_tuesday">úterý</string>
+ <string name="day_of_week_long_wednesday">středa</string>
+ <string name="day_of_week_long_thursday">čtvrtek</string>
+ <string name="day_of_week_long_friday">pátek</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">ne</string>
+ <string name="day_of_week_medium_monday">po</string>
+ <string name="day_of_week_medium_tuesday">út</string>
+ <string name="day_of_week_medium_wednesday">st</string>
+ <string name="day_of_week_medium_thursday">čt</string>
+ <string name="day_of_week_medium_friday">pá</string>
+ <string name="day_of_week_medium_saturday">so</string>
+
+ <string name="day_of_week_short_sunday">ne</string>
+ <string name="day_of_week_short_monday">po</string>
+ <string name="day_of_week_short_tuesday">út</string>
+ <string name="day_of_week_short_wednesday">st</string>
+ <string name="day_of_week_short_thursday">čt</string>
+ <string name="day_of_week_short_friday">pá</string>
+ <string name="day_of_week_short_saturday">so</string>
+
+ <string name="day_of_week_shortest_sunday">N</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">Ú</string>
+ <string name="day_of_week_shortest_wednesday">S</string>
+ <string name="day_of_week_shortest_thursday">Č</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">dop.</string>
+ <string name="pm">odp.</string>
+ <string name="yesterday">Včera</string>
+ <string name="today">Dnes</string>
+ <string name="tomorrow">Zítra</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%-e.%-m.%Y</string>
+ <string name="numeric_date_format">d.M.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 35a3f9a..c3860d4 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Heslo"</string>
<string name="lockscreen_glogin_submit_button">"Přihlásit se"</string>
<string name="lockscreen_glogin_invalid_input">"Neplatné uživatelské jméno nebo heslo."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Vymazat oznámení"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"enter"</string>
<string name="menu_delete_shortcut_label">"smazat"</string>
<string name="search_go">"Hledat"</string>
- <string name="today">"Dnes"</string>
- <string name="yesterday">"Včera"</string>
- <string name="tomorrow">"Zítra"</string>
<string name="oneMonthDurationPast">"před 1 měsícem"</string>
<string name="beforeOneMonthDurationPast">"Déle než před 1 měsícem"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"týd."</string>
<string name="year">"rokem"</string>
<string name="years">"lety"</string>
- <string name="sunday">"neděle"</string>
- <string name="monday">"pondělí"</string>
- <string name="tuesday">"úterý"</string>
- <string name="wednesday">"středa"</string>
- <string name="thursday">"čtvrtek"</string>
- <string name="friday">"pátek"</string>
- <string name="saturday">"sobota"</string>
<string name="every_weekday">"Každý pracovní den (Po – Pá)"</string>
<string name="daily">"Denně"</string>
<string name="weekly">"Každý týden v <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Omlouváme se, ale toto video nelze přenášet datovým proudem do tohoto zařízení."</string>
<string name="VideoView_error_text_unknown">"Toto video bohužel nelze přehrát."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"dop."</string>
- <string name="pm">"odp."</string>
- <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"poledne"</string>
<string name="Noon">"Poledne"</string>
<string name="midnight">"půlnoc"</string>
<string name="Midnight">"Půlnoc"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"neděle"</string>
- <string name="day_of_week_long_monday">"pondělí"</string>
- <string name="day_of_week_long_tuesday">"úterý"</string>
- <string name="day_of_week_long_wednesday">"středa"</string>
- <string name="day_of_week_long_thursday">"čtvrtek"</string>
- <string name="day_of_week_long_friday">"pátek"</string>
- <string name="day_of_week_long_saturday">"sobota"</string>
- <string name="day_of_week_medium_sunday">"Ne"</string>
- <string name="day_of_week_medium_monday">"Po"</string>
- <string name="day_of_week_medium_tuesday">"Út"</string>
- <string name="day_of_week_medium_wednesday">"St"</string>
- <string name="day_of_week_medium_thursday">"Čt"</string>
- <string name="day_of_week_medium_friday">"Pá"</string>
- <string name="day_of_week_medium_saturday">"So"</string>
- <string name="day_of_week_short_sunday">"Ne"</string>
- <string name="day_of_week_short_monday">"Po"</string>
- <string name="day_of_week_short_tuesday">"Út"</string>
- <string name="day_of_week_short_wednesday">"St"</string>
- <string name="day_of_week_short_thursday">"Čt"</string>
- <string name="day_of_week_short_friday">"Pá"</string>
- <string name="day_of_week_short_saturday">"So"</string>
- <string name="day_of_week_shorter_sunday">"Ne"</string>
- <string name="day_of_week_shorter_monday">"Po"</string>
- <string name="day_of_week_shorter_tuesday">"Út"</string>
- <string name="day_of_week_shorter_wednesday">"St"</string>
- <string name="day_of_week_shorter_thursday">"Čt"</string>
- <string name="day_of_week_shorter_friday">"Pá"</string>
- <string name="day_of_week_shorter_saturday">"So"</string>
- <string name="day_of_week_shortest_sunday">"Ne"</string>
- <string name="day_of_week_shortest_monday">"Po"</string>
- <string name="day_of_week_shortest_tuesday">"Čt"</string>
- <string name="day_of_week_shortest_wednesday">"St"</string>
- <string name="day_of_week_shortest_thursday">"Čt"</string>
- <string name="day_of_week_shortest_friday">"Pá"</string>
- <string name="day_of_week_shortest_saturday">"So"</string>
- <string name="month_long_january">"leden"</string>
- <string name="month_long_february">"únor"</string>
- <string name="month_long_march">"březen"</string>
- <string name="month_long_april">"duben"</string>
- <string name="month_long_may">"květen"</string>
- <string name="month_long_june">"červen"</string>
- <string name="month_long_july">"červenec"</string>
- <string name="month_long_august">"srpen"</string>
- <string name="month_long_september">"září"</string>
- <string name="month_long_october">"říjen"</string>
- <string name="month_long_november">"listopad"</string>
- <string name="month_long_december">"prosinec"</string>
- <string name="month_medium_january">"leden"</string>
- <string name="month_medium_february">"únor"</string>
- <string name="month_medium_march">"březen"</string>
- <string name="month_medium_april">"duben"</string>
- <string name="month_medium_may">"květen"</string>
- <string name="month_medium_june">"červen"</string>
- <string name="month_medium_july">"červenec"</string>
- <string name="month_medium_august">"srpen"</string>
- <string name="month_medium_september">"září"</string>
- <string name="month_medium_october">"říjen"</string>
- <string name="month_medium_november">"listopad"</string>
- <string name="month_medium_december">"prosinec"</string>
- <string name="month_shortest_january">"1."</string>
- <string name="month_shortest_february">"2."</string>
- <string name="month_shortest_march">"Po"</string>
- <string name="month_shortest_april">"4."</string>
- <string name="month_shortest_may">"5."</string>
- <string name="month_shortest_june">"6."</string>
- <string name="month_shortest_july">"7."</string>
- <string name="month_shortest_august">"8."</string>
- <string name="month_shortest_september">"9."</string>
- <string name="month_shortest_october">"10."</string>
- <string name="month_shortest_november">"11."</string>
- <string name="month_shortest_december">"12."</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Vybrat vše"</string>
diff --git a/core/res/res/values-da-rDK/donottranslate-cldr.xml b/core/res/res/values-da-rDK/donottranslate-cldr.xml
new file mode 100644
index 0000000..38097bd
--- /dev/null
+++ b/core/res/res/values-da-rDK/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januar</string>
+ <string name="month_long_standalone_february">februar</string>
+ <string name="month_long_standalone_march">marts</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">maj</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">august</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januar</string>
+ <string name="month_long_february">februar</string>
+ <string name="month_long_march">marts</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">maj</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">august</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mar.</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">maj</string>
+ <string name="month_medium_june">jun.</string>
+ <string name="month_medium_july">jul.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sep.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">søndag</string>
+ <string name="day_of_week_long_monday">mandag</string>
+ <string name="day_of_week_long_tuesday">tirsdag</string>
+ <string name="day_of_week_long_wednesday">onsdag</string>
+ <string name="day_of_week_long_thursday">torsdag</string>
+ <string name="day_of_week_long_friday">fredag</string>
+ <string name="day_of_week_long_saturday">lørdag</string>
+
+ <string name="day_of_week_medium_sunday">søn</string>
+ <string name="day_of_week_medium_monday">man</string>
+ <string name="day_of_week_medium_tuesday">tir</string>
+ <string name="day_of_week_medium_wednesday">ons</string>
+ <string name="day_of_week_medium_thursday">tor</string>
+ <string name="day_of_week_medium_friday">fre</string>
+ <string name="day_of_week_medium_saturday">lør</string>
+
+ <string name="day_of_week_short_sunday">søn</string>
+ <string name="day_of_week_short_monday">man</string>
+ <string name="day_of_week_short_tuesday">tir</string>
+ <string name="day_of_week_short_wednesday">ons</string>
+ <string name="day_of_week_short_thursday">tor</string>
+ <string name="day_of_week_short_friday">fre</string>
+ <string name="day_of_week_short_saturday">lør</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">O</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">L</string>
+
+ <string name="am">f.m.</string>
+ <string name="pm">e.m.</string>
+ <string name="yesterday">i går</string>
+ <string name="today">i dag</string>
+ <string name="tomorrow">i morgen</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e. %b %Y</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%b</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de-rAT/donottranslate-cldr.xml b/core/res/res/values-de-rAT/donottranslate-cldr.xml
new file mode 100644
index 0000000..ad35fee
--- /dev/null
+++ b/core/res/res/values-de-rAT/donottranslate-cldr.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Jänner</string>
+
+ <string name="month_long_january">Jänner</string>
+
+ <string name="month_medium_january">Jän</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sonntag</string>
+ <string name="day_of_week_long_monday">Montag</string>
+ <string name="day_of_week_long_tuesday">Dienstag</string>
+ <string name="day_of_week_long_wednesday">Mittwoch</string>
+ <string name="day_of_week_long_thursday">Donnerstag</string>
+ <string name="day_of_week_long_friday">Freitag</string>
+ <string name="day_of_week_long_saturday">Samstag</string>
+
+ <string name="day_of_week_medium_sunday">So.</string>
+ <string name="day_of_week_medium_monday">Mo.</string>
+ <string name="day_of_week_medium_tuesday">Di.</string>
+ <string name="day_of_week_medium_wednesday">Mi.</string>
+ <string name="day_of_week_medium_thursday">Do.</string>
+ <string name="day_of_week_medium_friday">Fr.</string>
+ <string name="day_of_week_medium_saturday">Sa.</string>
+
+ <string name="day_of_week_short_sunday">So.</string>
+ <string name="day_of_week_short_monday">Mo.</string>
+ <string name="day_of_week_short_tuesday">Di.</string>
+ <string name="day_of_week_short_wednesday">Mi.</string>
+ <string name="day_of_week_short_thursday">Do.</string>
+ <string name="day_of_week_short_friday">Fr.</string>
+ <string name="day_of_week_short_saturday">Sa.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">vorm.</string>
+ <string name="pm">nachm.</string>
+ <string name="yesterday">Gestern</string>
+ <string name="today">Heute</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%d. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de-rCH/donottranslate-cldr.xml b/core/res/res/values-de-rCH/donottranslate-cldr.xml
new file mode 100644
index 0000000..c8e0de8
--- /dev/null
+++ b/core/res/res/values-de-rCH/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Januar</string>
+ <string name="month_long_standalone_february">Februar</string>
+ <string name="month_long_standalone_march">März</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">Mai</string>
+ <string name="month_long_standalone_june">Juni</string>
+ <string name="month_long_standalone_july">Juli</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">Oktober</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">Dezember</string>
+
+ <string name="month_long_january">Januar</string>
+ <string name="month_long_february">Februar</string>
+ <string name="month_long_march">März</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">Mai</string>
+ <string name="month_long_june">Juni</string>
+ <string name="month_long_july">Juli</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">Oktober</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">Dezember</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mär</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">Mai</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Okt</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sonntag</string>
+ <string name="day_of_week_long_monday">Montag</string>
+ <string name="day_of_week_long_tuesday">Dienstag</string>
+ <string name="day_of_week_long_wednesday">Mittwoch</string>
+ <string name="day_of_week_long_thursday">Donnerstag</string>
+ <string name="day_of_week_long_friday">Freitag</string>
+ <string name="day_of_week_long_saturday">Samstag</string>
+
+ <string name="day_of_week_medium_sunday">So.</string>
+ <string name="day_of_week_medium_monday">Mo.</string>
+ <string name="day_of_week_medium_tuesday">Di.</string>
+ <string name="day_of_week_medium_wednesday">Mi.</string>
+ <string name="day_of_week_medium_thursday">Do.</string>
+ <string name="day_of_week_medium_friday">Fr.</string>
+ <string name="day_of_week_medium_saturday">Sa.</string>
+
+ <string name="day_of_week_short_sunday">So.</string>
+ <string name="day_of_week_short_monday">Mo.</string>
+ <string name="day_of_week_short_tuesday">Di.</string>
+ <string name="day_of_week_short_wednesday">Mi.</string>
+ <string name="day_of_week_short_thursday">Do.</string>
+ <string name="day_of_week_short_friday">Fr.</string>
+ <string name="day_of_week_short_saturday">Sa.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">vorm.</string>
+ <string name="pm">nachm.</string>
+ <string name="yesterday">Gestern</string>
+ <string name="today">Heute</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de-rDE/donottranslate-cldr.xml b/core/res/res/values-de-rDE/donottranslate-cldr.xml
new file mode 100644
index 0000000..c8e0de8
--- /dev/null
+++ b/core/res/res/values-de-rDE/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Januar</string>
+ <string name="month_long_standalone_february">Februar</string>
+ <string name="month_long_standalone_march">März</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">Mai</string>
+ <string name="month_long_standalone_june">Juni</string>
+ <string name="month_long_standalone_july">Juli</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">Oktober</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">Dezember</string>
+
+ <string name="month_long_january">Januar</string>
+ <string name="month_long_february">Februar</string>
+ <string name="month_long_march">März</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">Mai</string>
+ <string name="month_long_june">Juni</string>
+ <string name="month_long_july">Juli</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">Oktober</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">Dezember</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mär</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">Mai</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Okt</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sonntag</string>
+ <string name="day_of_week_long_monday">Montag</string>
+ <string name="day_of_week_long_tuesday">Dienstag</string>
+ <string name="day_of_week_long_wednesday">Mittwoch</string>
+ <string name="day_of_week_long_thursday">Donnerstag</string>
+ <string name="day_of_week_long_friday">Freitag</string>
+ <string name="day_of_week_long_saturday">Samstag</string>
+
+ <string name="day_of_week_medium_sunday">So.</string>
+ <string name="day_of_week_medium_monday">Mo.</string>
+ <string name="day_of_week_medium_tuesday">Di.</string>
+ <string name="day_of_week_medium_wednesday">Mi.</string>
+ <string name="day_of_week_medium_thursday">Do.</string>
+ <string name="day_of_week_medium_friday">Fr.</string>
+ <string name="day_of_week_medium_saturday">Sa.</string>
+
+ <string name="day_of_week_short_sunday">So.</string>
+ <string name="day_of_week_short_monday">Mo.</string>
+ <string name="day_of_week_short_tuesday">Di.</string>
+ <string name="day_of_week_short_wednesday">Mi.</string>
+ <string name="day_of_week_short_thursday">Do.</string>
+ <string name="day_of_week_short_friday">Fr.</string>
+ <string name="day_of_week_short_saturday">Sa.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">vorm.</string>
+ <string name="pm">nachm.</string>
+ <string name="yesterday">Gestern</string>
+ <string name="today">Heute</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de-rLI/donottranslate-cldr.xml b/core/res/res/values-de-rLI/donottranslate-cldr.xml
new file mode 100644
index 0000000..c8e0de8
--- /dev/null
+++ b/core/res/res/values-de-rLI/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Januar</string>
+ <string name="month_long_standalone_february">Februar</string>
+ <string name="month_long_standalone_march">März</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">Mai</string>
+ <string name="month_long_standalone_june">Juni</string>
+ <string name="month_long_standalone_july">Juli</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">Oktober</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">Dezember</string>
+
+ <string name="month_long_january">Januar</string>
+ <string name="month_long_february">Februar</string>
+ <string name="month_long_march">März</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">Mai</string>
+ <string name="month_long_june">Juni</string>
+ <string name="month_long_july">Juli</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">Oktober</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">Dezember</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mär</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">Mai</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Okt</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sonntag</string>
+ <string name="day_of_week_long_monday">Montag</string>
+ <string name="day_of_week_long_tuesday">Dienstag</string>
+ <string name="day_of_week_long_wednesday">Mittwoch</string>
+ <string name="day_of_week_long_thursday">Donnerstag</string>
+ <string name="day_of_week_long_friday">Freitag</string>
+ <string name="day_of_week_long_saturday">Samstag</string>
+
+ <string name="day_of_week_medium_sunday">So.</string>
+ <string name="day_of_week_medium_monday">Mo.</string>
+ <string name="day_of_week_medium_tuesday">Di.</string>
+ <string name="day_of_week_medium_wednesday">Mi.</string>
+ <string name="day_of_week_medium_thursday">Do.</string>
+ <string name="day_of_week_medium_friday">Fr.</string>
+ <string name="day_of_week_medium_saturday">Sa.</string>
+
+ <string name="day_of_week_short_sunday">So.</string>
+ <string name="day_of_week_short_monday">Mo.</string>
+ <string name="day_of_week_short_tuesday">Di.</string>
+ <string name="day_of_week_short_wednesday">Mi.</string>
+ <string name="day_of_week_short_thursday">Do.</string>
+ <string name="day_of_week_short_friday">Fr.</string>
+ <string name="day_of_week_short_saturday">Sa.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">vorm.</string>
+ <string name="pm">nachm.</string>
+ <string name="yesterday">Gestern</string>
+ <string name="today">Heute</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
new file mode 100644
index 0000000..c8e0de8
--- /dev/null
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Januar</string>
+ <string name="month_long_standalone_february">Februar</string>
+ <string name="month_long_standalone_march">März</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">Mai</string>
+ <string name="month_long_standalone_june">Juni</string>
+ <string name="month_long_standalone_july">Juli</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">Oktober</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">Dezember</string>
+
+ <string name="month_long_january">Januar</string>
+ <string name="month_long_february">Februar</string>
+ <string name="month_long_march">März</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">Mai</string>
+ <string name="month_long_june">Juni</string>
+ <string name="month_long_july">Juli</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">Oktober</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">Dezember</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mär</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">Mai</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Okt</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sonntag</string>
+ <string name="day_of_week_long_monday">Montag</string>
+ <string name="day_of_week_long_tuesday">Dienstag</string>
+ <string name="day_of_week_long_wednesday">Mittwoch</string>
+ <string name="day_of_week_long_thursday">Donnerstag</string>
+ <string name="day_of_week_long_friday">Freitag</string>
+ <string name="day_of_week_long_saturday">Samstag</string>
+
+ <string name="day_of_week_medium_sunday">So.</string>
+ <string name="day_of_week_medium_monday">Mo.</string>
+ <string name="day_of_week_medium_tuesday">Di.</string>
+ <string name="day_of_week_medium_wednesday">Mi.</string>
+ <string name="day_of_week_medium_thursday">Do.</string>
+ <string name="day_of_week_medium_friday">Fr.</string>
+ <string name="day_of_week_medium_saturday">Sa.</string>
+
+ <string name="day_of_week_short_sunday">So.</string>
+ <string name="day_of_week_short_monday">Mo.</string>
+ <string name="day_of_week_short_tuesday">Di.</string>
+ <string name="day_of_week_short_wednesday">Mi.</string>
+ <string name="day_of_week_short_thursday">Do.</string>
+ <string name="day_of_week_short_friday">Fr.</string>
+ <string name="day_of_week_short_saturday">Sa.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">vorm.</string>
+ <string name="pm">nachm.</string>
+ <string name="yesterday">Gestern</string>
+ <string name="today">Heute</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 674c64b..d121801 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Passwort"</string>
<string name="lockscreen_glogin_submit_button">"Anmelden"</string>
<string name="lockscreen_glogin_invalid_input">"Ungültiger Nutzername oder ungültiges Passwort."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Benachrichtigungen löschen"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"Enter"</string>
<string name="menu_delete_shortcut_label">"löschen"</string>
<string name="search_go">"Suche"</string>
- <string name="today">"Heute"</string>
- <string name="yesterday">"Gestern"</string>
- <string name="tomorrow">"Morgen"</string>
<string name="oneMonthDurationPast">"Vor 1 Monat"</string>
<string name="beforeOneMonthDurationPast">"Vor mehr als 1 Monat"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"Wochen"</string>
<string name="year">"Jahr"</string>
<string name="years">"Jahre"</string>
- <string name="sunday">"Sonntag"</string>
- <string name="monday">"Montag"</string>
- <string name="tuesday">"Dienstag"</string>
- <string name="wednesday">"Mittwoch"</string>
- <string name="thursday">"Donnerstag"</string>
- <string name="friday">"Freitag"</string>
- <string name="saturday">"Samstag"</string>
<string name="every_weekday">"Jeden Wochentag (Mo-Fr)"</string>
<string name="daily">"Täglich"</string>
<string name="weekly">"Jede Woche am <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Leider ist dieses Video nicht für Streaming auf diesem Gerät gültig."</string>
<string name="VideoView_error_text_unknown">"Dieses Video kann leider nicht abgespielt werden."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">".."</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"Mittag"</string>
<string name="Noon">"Mittag"</string>
<string name="midnight">"Mitternacht"</string>
<string name="Midnight">"Mitternacht"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"Sonntag"</string>
- <string name="day_of_week_long_monday">"Montag"</string>
- <string name="day_of_week_long_tuesday">"Dienstag"</string>
- <string name="day_of_week_long_wednesday">"Mittwoch"</string>
- <string name="day_of_week_long_thursday">"Donnerstag"</string>
- <string name="day_of_week_long_friday">"Freitag"</string>
- <string name="day_of_week_long_saturday">"Samstag"</string>
- <string name="day_of_week_medium_sunday">"So"</string>
- <string name="day_of_week_medium_monday">"Mo"</string>
- <string name="day_of_week_medium_tuesday">"Di"</string>
- <string name="day_of_week_medium_wednesday">"Mi"</string>
- <string name="day_of_week_medium_thursday">"Do"</string>
- <string name="day_of_week_medium_friday">"Fr"</string>
- <string name="day_of_week_medium_saturday">"Sa"</string>
- <string name="day_of_week_short_sunday">"So"</string>
- <string name="day_of_week_short_monday">"Mo"</string>
- <string name="day_of_week_short_tuesday">"Di"</string>
- <string name="day_of_week_short_wednesday">"Mi"</string>
- <string name="day_of_week_short_thursday">"Do"</string>
- <string name="day_of_week_short_friday">"Fr"</string>
- <string name="day_of_week_short_saturday">"Sa"</string>
- <string name="day_of_week_shorter_sunday">"So"</string>
- <string name="day_of_week_shorter_monday">"März"</string>
- <string name="day_of_week_shorter_tuesday">"Di"</string>
- <string name="day_of_week_shorter_wednesday">"Mi"</string>
- <string name="day_of_week_shorter_thursday">"Do"</string>
- <string name="day_of_week_shorter_friday">"Fr"</string>
- <string name="day_of_week_shorter_saturday">"Sa"</string>
- <string name="day_of_week_shortest_sunday">"Sep"</string>
- <string name="day_of_week_shortest_monday">"Mo"</string>
- <string name="day_of_week_shortest_tuesday">"Do"</string>
- <string name="day_of_week_shortest_wednesday">"Mi"</string>
- <string name="day_of_week_shortest_thursday">"Do"</string>
- <string name="day_of_week_shortest_friday">"Fr"</string>
- <string name="day_of_week_shortest_saturday">"Sa"</string>
- <string name="month_long_january">"Januar"</string>
- <string name="month_long_february">"Februar"</string>
- <string name="month_long_march">"März"</string>
- <string name="month_long_april">"April"</string>
- <string name="month_long_may">"Mai"</string>
- <string name="month_long_june">"Juni"</string>
- <string name="month_long_july">"Juli"</string>
- <string name="month_long_august">"August"</string>
- <string name="month_long_september">"September"</string>
- <string name="month_long_october">"Oktober"</string>
- <string name="month_long_november">"November"</string>
- <string name="month_long_december">"Dezember"</string>
- <string name="month_medium_january">"Jan."</string>
- <string name="month_medium_february">"Feb."</string>
- <string name="month_medium_march">"März"</string>
- <string name="month_medium_april">"Apr."</string>
- <string name="month_medium_may">"Mai"</string>
- <string name="month_medium_june">"Juni"</string>
- <string name="month_medium_july">"Juli"</string>
- <string name="month_medium_august">"Aug"</string>
- <string name="month_medium_september">"Sep."</string>
- <string name="month_medium_october">"Okt."</string>
- <string name="month_medium_november">"Nov."</string>
- <string name="month_medium_december">"Dez."</string>
- <string name="month_shortest_january">"Juli"</string>
- <string name="month_shortest_february">"Fr"</string>
- <string name="month_shortest_march">"März"</string>
- <string name="month_shortest_april">"Apr"</string>
- <string name="month_shortest_may">"Mo"</string>
- <string name="month_shortest_june">"Juni"</string>
- <string name="month_shortest_july">"Juli"</string>
- <string name="month_shortest_august">"Aug."</string>
- <string name="month_shortest_september">"Sep"</string>
- <string name="month_shortest_october">"Okt."</string>
- <string name="month_shortest_november">"No"</string>
- <string name="month_shortest_december">"Dez."</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Alles auswählen"</string>
diff --git a/core/res/res/values-el-rGR/donottranslate-cldr.xml b/core/res/res/values-el-rGR/donottranslate-cldr.xml
new file mode 100644
index 0000000..9d2a0aa
--- /dev/null
+++ b/core/res/res/values-el-rGR/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Ιανουάριος</string>
+ <string name="month_long_standalone_february">Φεβρουάριος</string>
+ <string name="month_long_standalone_march">Μάρτιος</string>
+ <string name="month_long_standalone_april">Απρίλιος</string>
+ <string name="month_long_standalone_may">Μάιος</string>
+ <string name="month_long_standalone_june">Ιούνιος</string>
+ <string name="month_long_standalone_july">Ιούλιος</string>
+ <string name="month_long_standalone_august">Αύγουστος</string>
+ <string name="month_long_standalone_september">Σεπτέμβριος</string>
+ <string name="month_long_standalone_october">Οκτώβριος</string>
+ <string name="month_long_standalone_november">Νοέμβριος</string>
+ <string name="month_long_standalone_december">Δεκέμβριος</string>
+
+ <string name="month_long_january">Ιανουαρίου</string>
+ <string name="month_long_february">Φεβρουαρίου</string>
+ <string name="month_long_march">Μαρτίου</string>
+ <string name="month_long_april">Απριλίου</string>
+ <string name="month_long_may">Μαΐου</string>
+ <string name="month_long_june">Ιουνίου</string>
+ <string name="month_long_july">Ιουλίου</string>
+ <string name="month_long_august">Αυγούστου</string>
+ <string name="month_long_september">Σεπτεμβρίου</string>
+ <string name="month_long_october">Οκτωβρίου</string>
+ <string name="month_long_november">Νοεμβρίου</string>
+ <string name="month_long_december">Δεκεμβρίου</string>
+
+ <string name="month_medium_january">Ιαν</string>
+ <string name="month_medium_february">Φεβ</string>
+ <string name="month_medium_march">Μαρ</string>
+ <string name="month_medium_april">Απρ</string>
+ <string name="month_medium_may">Μαϊ</string>
+ <string name="month_medium_june">Ιουν</string>
+ <string name="month_medium_july">Ιουλ</string>
+ <string name="month_medium_august">Αυγ</string>
+ <string name="month_medium_september">Σεπ</string>
+ <string name="month_medium_october">Οκτ</string>
+ <string name="month_medium_november">Νοε</string>
+ <string name="month_medium_december">Δεκ</string>
+
+ <string name="month_shortest_january">Ι</string>
+ <string name="month_shortest_february">Φ</string>
+ <string name="month_shortest_march">Μ</string>
+ <string name="month_shortest_april">Α</string>
+ <string name="month_shortest_may">Μ</string>
+ <string name="month_shortest_june">Ι</string>
+ <string name="month_shortest_july">Ι</string>
+ <string name="month_shortest_august">Α</string>
+ <string name="month_shortest_september">Σ</string>
+ <string name="month_shortest_october">Ο</string>
+ <string name="month_shortest_november">Ν</string>
+ <string name="month_shortest_december">Δ</string>
+
+ <string name="day_of_week_long_sunday">Κυριακή</string>
+ <string name="day_of_week_long_monday">Δευτέρα</string>
+ <string name="day_of_week_long_tuesday">Τρίτη</string>
+ <string name="day_of_week_long_wednesday">Τετάρτη</string>
+ <string name="day_of_week_long_thursday">Πέμπτη</string>
+ <string name="day_of_week_long_friday">Παρασκευή</string>
+ <string name="day_of_week_long_saturday">Σάββατο</string>
+
+ <string name="day_of_week_medium_sunday">Κυρ</string>
+ <string name="day_of_week_medium_monday">Δευ</string>
+ <string name="day_of_week_medium_tuesday">Τρι</string>
+ <string name="day_of_week_medium_wednesday">Τετ</string>
+ <string name="day_of_week_medium_thursday">Πεμ</string>
+ <string name="day_of_week_medium_friday">Παρ</string>
+ <string name="day_of_week_medium_saturday">Σαβ</string>
+
+ <string name="day_of_week_short_sunday">Κυρ</string>
+ <string name="day_of_week_short_monday">Δευ</string>
+ <string name="day_of_week_short_tuesday">Τρι</string>
+ <string name="day_of_week_short_wednesday">Τετ</string>
+ <string name="day_of_week_short_thursday">Πεμ</string>
+ <string name="day_of_week_short_friday">Παρ</string>
+ <string name="day_of_week_short_saturday">Σαβ</string>
+
+ <string name="day_of_week_shortest_sunday">Κ</string>
+ <string name="day_of_week_shortest_monday">Δ</string>
+ <string name="day_of_week_shortest_tuesday">Τ</string>
+ <string name="day_of_week_shortest_wednesday">Τ</string>
+ <string name="day_of_week_shortest_thursday">Π</string>
+ <string name="day_of_week_shortest_friday">Π</string>
+ <string name="day_of_week_shortest_saturday">Σ</string>
+
+ <string name="am">π.μ.</string>
+ <string name="pm">μ.μ.</string>
+ <string name="yesterday">Χτες</string>
+ <string name="today">Σήμερα</string>
+ <string name="tomorrow">Αύριο</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+ <string name="abbrev_month_day_year">%d %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rAU/donottranslate-cldr.xml b/core/res/res/values-en-rAU/donottranslate-cldr.xml
new file mode 100644
index 0000000..7ed029c
--- /dev/null
+++ b/core/res/res/values-en-rAU/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-e/%m/%Y</string>
+ <string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 9da879b..d482222 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -710,7 +710,6 @@
<!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) -->
<skip />
<!-- no translation found for status_bar_time_format (2168573805413119180) -->
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
<!-- no translation found for hour_minute_ampm (1850330605794978742) -->
<skip />
<!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
@@ -864,7 +863,6 @@
<!-- from values-de/strings.xml and removal of all the german craziyness-->
<skip />
<!-- no translation found for numeric_date (5120078478872821100) -->
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
@@ -888,11 +886,9 @@
<!-- no translation found for full_date_month_first (6011143962222283357) -->
<skip />
<!-- no translation found for full_date_day_first (8621594762705478189) -->
- <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for medium_date_month_first (48990963718825728) -->
<skip />
<!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
<skip />
<!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
@@ -906,15 +902,12 @@
<!-- no translation found for Midnight (1260172107848123187) -->
<skip />
<!-- no translation found for month_day (3356633704511426364) -->
- <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string>
<!-- no translation found for month (3017405760734206414) -->
<skip />
<!-- no translation found for month_day_year (2435948225709176752) -->
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for month_year (6228414124777343135) -->
<skip />
<!-- no translation found for time_of_day (8375993139317154157) -->
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<!-- no translation found for date_and_time (9197690194373107109) -->
<skip />
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
@@ -922,7 +915,6 @@
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for date_and_time (353898423108629694) -->
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
@@ -968,11 +960,9 @@
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
<!-- no translation found for abbrev_month_day (458867920693482757) -->
- <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (1674509986330181349) -->
<skip />
<!-- no translation found for day_of_week_long_sunday (9057662850446501884) -->
diff --git a/core/res/res/values-en-rCA/donottranslate-cldr.xml b/core/res/res/values-en-rCA/donottranslate-cldr.xml
new file mode 100644
index 0000000..2fb3ef6
--- /dev/null
+++ b/core/res/res/values-en-rCA/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%Y-%m-%d</string>
+ <string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="month_day_year">%B %-e, %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %Y-%m-%d</string>
+ <string name="abbrev_month_day_year">%Y-%m-%d</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rGB/donottranslate-cldr.xml b/core/res/res/values-en-rGB/donottranslate-cldr.xml
new file mode 100644
index 0000000..0c544af
--- /dev/null
+++ b/core/res/res/values-en-rGB/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rIE/donottranslate-cldr.xml b/core/res/res/values-en-rIE/donottranslate-cldr.xml
new file mode 100644
index 0000000..0c544af
--- /dev/null
+++ b/core/res/res/values-en-rIE/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rIN/donottranslate-cldr.xml b/core/res/res/values-en-rIN/donottranslate-cldr.xml
new file mode 100644
index 0000000..823c3c1
--- /dev/null
+++ b/core/res/res/values-en-rIN/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d-%b-%Y</string>
+ <string name="abbrev_month_day_year">%d-%b-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rNZ/donottranslate-cldr.xml b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
new file mode 100644
index 0000000..bcd976c
--- /dev/null
+++ b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-e/%m/%Y</string>
+ <string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %-e/%m/%Y</string>
+ <string name="abbrev_month_day_year">%-e/%m/%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rSG/donottranslate-cldr.xml b/core/res/res/values-en-rSG/donottranslate-cldr.xml
new file mode 100644
index 0000000..f305948
--- /dev/null
+++ b/core/res/res/values-en-rSG/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-m/%-e/%Y</string>
+ <string name="numeric_date_format">M/d/yyyy</string>
+ <string name="month_day_year">%B %-e, %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="abbrev_month_day_year">%b %-e, %Y</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rSG/strings.xml b/core/res/res/values-en-rSG/strings.xml
index 6850a5d..1c6eda2 100644
--- a/core/res/res/values-en-rSG/strings.xml
+++ b/core/res/res/values-en-rSG/strings.xml
@@ -710,7 +710,6 @@
<!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) -->
<skip />
<!-- no translation found for status_bar_time_format (2168573805413119180) -->
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
<!-- no translation found for hour_minute_ampm (1850330605794978742) -->
<skip />
<!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
@@ -867,7 +866,6 @@
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for numeric_date (5537215108967329745) -->
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for date1_date2 (377057563556488062) -->
@@ -885,11 +883,9 @@
<!-- no translation found for full_date_month_first (6011143962222283357) -->
<skip />
<!-- no translation found for full_date_day_first (8621594762705478189) -->
- <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for medium_date_month_first (48990963718825728) -->
<skip />
<!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
<skip />
<!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
@@ -903,17 +899,13 @@
<!-- no translation found for Midnight (1260172107848123187) -->
<skip />
<!-- no translation found for month_day (3356633704511426364) -->
- <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string>
<!-- no translation found for month (3017405760734206414) -->
<skip />
<!-- no translation found for month_day_year (2435948225709176752) -->
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for month_year (6228414124777343135) -->
<skip />
<!-- no translation found for time_of_day (8375993139317154157) -->
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<!-- no translation found for date_and_time (9197690194373107109) -->
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
@@ -963,11 +955,9 @@
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
<!-- no translation found for abbrev_month_day (458867920693482757) -->
- <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (1674509986330181349) -->
<skip />
<!-- no translation found for day_of_week_long_sunday (9057662850446501884) -->
diff --git a/core/res/res/values-en-rUS/donottranslate-cldr.xml b/core/res/res/values-en-rUS/donottranslate-cldr.xml
new file mode 100644
index 0000000..f305948
--- /dev/null
+++ b/core/res/res/values-en-rUS/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-m/%-e/%Y</string>
+ <string name="numeric_date_format">M/d/yyyy</string>
+ <string name="month_day_year">%B %-e, %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="abbrev_month_day_year">%b %-e, %Y</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-en-rZA/donottranslate-cldr.xml b/core/res/res/values-en-rZA/donottranslate-cldr.xml
new file mode 100644
index 0000000..633c761
--- /dev/null
+++ b/core/res/res/values-en-rZA/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%Y/%m/%d</string>
+ <string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+ <string name="abbrev_month_day_year">%d %b %Y</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-es-rES/donottranslate-cldr.xml b/core/res/res/values-es-rES/donottranslate-cldr.xml
new file mode 100644
index 0000000..967a639
--- /dev/null
+++ b/core/res/res/values-es-rES/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">enero</string>
+ <string name="month_long_standalone_february">febrero</string>
+ <string name="month_long_standalone_march">marzo</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">mayo</string>
+ <string name="month_long_standalone_june">junio</string>
+ <string name="month_long_standalone_july">julio</string>
+ <string name="month_long_standalone_august">agosto</string>
+ <string name="month_long_standalone_september">septiembre</string>
+ <string name="month_long_standalone_october">octubre</string>
+ <string name="month_long_standalone_november">noviembre</string>
+ <string name="month_long_standalone_december">diciembre</string>
+
+ <string name="month_long_january">enero</string>
+ <string name="month_long_february">febrero</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">mayo</string>
+ <string name="month_long_june">junio</string>
+ <string name="month_long_july">julio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">septiembre</string>
+ <string name="month_long_october">octubre</string>
+ <string name="month_long_november">noviembre</string>
+ <string name="month_long_december">diciembre</string>
+
+ <string name="month_medium_january">ene</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">abr</string>
+ <string name="month_medium_may">may</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">oct</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">E</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">lunes</string>
+ <string name="day_of_week_long_tuesday">martes</string>
+ <string name="day_of_week_long_wednesday">miércoles</string>
+ <string name="day_of_week_long_thursday">jueves</string>
+ <string name="day_of_week_long_friday">viernes</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mié</string>
+ <string name="day_of_week_medium_thursday">jue</string>
+ <string name="day_of_week_medium_friday">vie</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mié</string>
+ <string name="day_of_week_short_thursday">jue</string>
+ <string name="day_of_week_short_friday">vie</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">ayer</string>
+ <string name="today">hoy</string>
+ <string name="tomorrow">mañana</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-es-rUS/donottranslate-cldr.xml b/core/res/res/values-es-rUS/donottranslate-cldr.xml
new file mode 100644
index 0000000..8668fda
--- /dev/null
+++ b/core/res/res/values-es-rUS/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">enero</string>
+ <string name="month_long_standalone_february">febrero</string>
+ <string name="month_long_standalone_march">marzo</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">mayo</string>
+ <string name="month_long_standalone_june">junio</string>
+ <string name="month_long_standalone_july">julio</string>
+ <string name="month_long_standalone_august">agosto</string>
+ <string name="month_long_standalone_september">septiembre</string>
+ <string name="month_long_standalone_october">octubre</string>
+ <string name="month_long_standalone_november">noviembre</string>
+ <string name="month_long_standalone_december">diciembre</string>
+
+ <string name="month_long_january">enero</string>
+ <string name="month_long_february">febrero</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">mayo</string>
+ <string name="month_long_june">junio</string>
+ <string name="month_long_july">julio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">septiembre</string>
+ <string name="month_long_october">octubre</string>
+ <string name="month_long_november">noviembre</string>
+ <string name="month_long_december">diciembre</string>
+
+ <string name="month_medium_january">ene</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">abr</string>
+ <string name="month_medium_may">may</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">oct</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">E</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">lunes</string>
+ <string name="day_of_week_long_tuesday">martes</string>
+ <string name="day_of_week_long_wednesday">miércoles</string>
+ <string name="day_of_week_long_thursday">jueves</string>
+ <string name="day_of_week_long_friday">viernes</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mié</string>
+ <string name="day_of_week_medium_thursday">jue</string>
+ <string name="day_of_week_medium_friday">vie</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mié</string>
+ <string name="day_of_week_short_thursday">jue</string>
+ <string name="day_of_week_short_friday">vie</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">ayer</string>
+ <string name="today">hoy</string>
+ <string name="tomorrow">mañana</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-m/%-e/%Y</string>
+ <string name="numeric_date_format">M/d/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="abbrev_month_day_year">%b %-e, %Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 7b60a39..6032321 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -436,9 +436,6 @@
<string name="lockscreen_glogin_password_hint">"Contraseña"</string>
<string name="lockscreen_glogin_submit_button">"Inicia sesión"</string>
<string name="lockscreen_glogin_invalid_input">"Nombre de usuario o contraseña incorrecta."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Borrar notificaciones"</string>
@@ -470,9 +467,6 @@
<string name="menu_enter_shortcut_label">"ingresar"</string>
<string name="menu_delete_shortcut_label">"borrar"</string>
<string name="search_go">"Buscar"</string>
- <string name="today">"Hoy"</string>
- <string name="yesterday">"Ayer"</string>
- <string name="tomorrow">"Mañana"</string>
<string name="oneMonthDurationPast">"hace 1 mes"</string>
<string name="beforeOneMonthDurationPast">"Anterior a 1 mes atrás"</string>
<plurals name="num_seconds_ago">
@@ -554,13 +548,6 @@
<string name="weeks">"semanas"</string>
<string name="year">"año"</string>
<string name="years">"años"</string>
- <string name="sunday">"Domingo"</string>
- <string name="monday">"Lunes"</string>
- <string name="tuesday">"Martes"</string>
- <string name="wednesday">"Miércoles"</string>
- <string name="thursday">"Jueves"</string>
- <string name="friday">"Viernes"</string>
- <string name="saturday">"Sábado"</string>
<string name="every_weekday">"Los días de semana (lunes a viernes)"</string>
<string name="daily">"Diariamente"</string>
<string name="weekly">"Semanalmente el día <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -570,9 +557,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Lo sentimos, este video no es válido para las transmisiones a este dispositivo."</string>
<string name="VideoView_error_text_unknown">"Lo sentimos, no se puede reproducir este video."</string>
<string name="VideoView_error_button">"Aceptar"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -584,23 +568,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"mediodía"</string>
<string name="Noon">"Mediodía"</string>
<string name="midnight">"medianoche"</string>
<string name="Midnight">"Medianoche"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -625,82 +598,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"Domingo"</string>
- <string name="day_of_week_long_monday">"Lunes"</string>
- <string name="day_of_week_long_tuesday">"Martes"</string>
- <string name="day_of_week_long_wednesday">"Miércoles"</string>
- <string name="day_of_week_long_thursday">"Jueves"</string>
- <string name="day_of_week_long_friday">"Viernes"</string>
- <string name="day_of_week_long_saturday">"Sábado"</string>
- <string name="day_of_week_medium_sunday">"Dom."</string>
- <string name="day_of_week_medium_monday">"Lun."</string>
- <string name="day_of_week_medium_tuesday">"Mar."</string>
- <string name="day_of_week_medium_wednesday">"Mié."</string>
- <string name="day_of_week_medium_thursday">"Jue."</string>
- <string name="day_of_week_medium_friday">"Vie."</string>
- <string name="day_of_week_medium_saturday">"Sáb."</string>
- <string name="day_of_week_short_sunday">"Dom."</string>
- <string name="day_of_week_short_monday">"Lun."</string>
- <string name="day_of_week_short_tuesday">"Mar."</string>
- <string name="day_of_week_short_wednesday">"Nosotros"</string>
- <string name="day_of_week_short_thursday">"Jue."</string>
- <string name="day_of_week_short_friday">"V"</string>
- <string name="day_of_week_short_saturday">"Sáb."</string>
- <string name="day_of_week_shorter_sunday">"Dom."</string>
- <string name="day_of_week_shorter_monday">"L"</string>
- <string name="day_of_week_shorter_tuesday">"Mar."</string>
- <string name="day_of_week_shorter_wednesday">"M"</string>
- <string name="day_of_week_shorter_thursday">"Jue."</string>
- <string name="day_of_week_shorter_friday">"V"</string>
- <string name="day_of_week_shorter_saturday">"Sáb."</string>
- <string name="day_of_week_shortest_sunday">"D"</string>
- <string name="day_of_week_shortest_monday">"L"</string>
- <string name="day_of_week_shortest_tuesday">"Mar."</string>
- <string name="day_of_week_shortest_wednesday">"M"</string>
- <string name="day_of_week_shortest_thursday">"Jue."</string>
- <string name="day_of_week_shortest_friday">"V"</string>
- <string name="day_of_week_shortest_saturday">"D"</string>
- <string name="month_long_january">"Enero"</string>
- <string name="month_long_february">"Febrero"</string>
- <string name="month_long_march">"Marzo"</string>
- <string name="month_long_april">"Abril"</string>
- <string name="month_long_may">"Mayo"</string>
- <string name="month_long_june">"Junio"</string>
- <string name="month_long_july">"Julio"</string>
- <string name="month_long_august">"Agosto"</string>
- <string name="month_long_september">"Septiembre"</string>
- <string name="month_long_october">"Octubre"</string>
- <string name="month_long_november">"Noviembre"</string>
- <string name="month_long_december">"Diciembre"</string>
- <string name="month_medium_january">"Ene."</string>
- <string name="month_medium_february">"Feb."</string>
- <string name="month_medium_march">"Mar."</string>
- <string name="month_medium_april">"Abr."</string>
- <string name="month_medium_may">"Mayo"</string>
- <string name="month_medium_june">"Jun."</string>
- <string name="month_medium_july">"Jul."</string>
- <string name="month_medium_august">"Ago."</string>
- <string name="month_medium_september">"Sep."</string>
- <string name="month_medium_october">"Oct."</string>
- <string name="month_medium_november">"Nov."</string>
- <string name="month_medium_december">"Dic."</string>
- <string name="month_shortest_january">"E"</string>
- <string name="month_shortest_february">"V"</string>
- <string name="month_shortest_march">"M"</string>
- <string name="month_shortest_april">"A"</string>
- <string name="month_shortest_may">"M"</string>
- <string name="month_shortest_june">"E"</string>
- <string name="month_shortest_july">"J"</string>
- <string name="month_shortest_august">"Ago."</string>
- <string name="month_shortest_september">"D"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"Dic."</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Seleccionar todos"</string>
diff --git a/core/res/res/values-es/donottranslate-cldr.xml b/core/res/res/values-es/donottranslate-cldr.xml
new file mode 100644
index 0000000..967a639
--- /dev/null
+++ b/core/res/res/values-es/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">enero</string>
+ <string name="month_long_standalone_february">febrero</string>
+ <string name="month_long_standalone_march">marzo</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">mayo</string>
+ <string name="month_long_standalone_june">junio</string>
+ <string name="month_long_standalone_july">julio</string>
+ <string name="month_long_standalone_august">agosto</string>
+ <string name="month_long_standalone_september">septiembre</string>
+ <string name="month_long_standalone_october">octubre</string>
+ <string name="month_long_standalone_november">noviembre</string>
+ <string name="month_long_standalone_december">diciembre</string>
+
+ <string name="month_long_january">enero</string>
+ <string name="month_long_february">febrero</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">mayo</string>
+ <string name="month_long_june">junio</string>
+ <string name="month_long_july">julio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">septiembre</string>
+ <string name="month_long_october">octubre</string>
+ <string name="month_long_november">noviembre</string>
+ <string name="month_long_december">diciembre</string>
+
+ <string name="month_medium_january">ene</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">abr</string>
+ <string name="month_medium_may">may</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">oct</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">E</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">lunes</string>
+ <string name="day_of_week_long_tuesday">martes</string>
+ <string name="day_of_week_long_wednesday">miércoles</string>
+ <string name="day_of_week_long_thursday">jueves</string>
+ <string name="day_of_week_long_friday">viernes</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mié</string>
+ <string name="day_of_week_medium_thursday">jue</string>
+ <string name="day_of_week_medium_friday">vie</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mié</string>
+ <string name="day_of_week_short_thursday">jue</string>
+ <string name="day_of_week_short_friday">vie</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">ayer</string>
+ <string name="today">hoy</string>
+ <string name="tomorrow">mañana</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a9f267a..c55e0ed 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Contraseña"</string>
<string name="lockscreen_glogin_submit_button">"Acceder"</string>
<string name="lockscreen_glogin_invalid_input">"Nombre de usuario o contraseña no válido"</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Cerrar notificaciones"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"intro"</string>
<string name="menu_delete_shortcut_label">"suprimir"</string>
<string name="search_go">"Buscar"</string>
- <string name="today">"Hoy"</string>
- <string name="yesterday">"Ayer"</string>
- <string name="tomorrow">"Mañana"</string>
<string name="oneMonthDurationPast">"Hace un mes"</string>
<string name="beforeOneMonthDurationPast">"Hace más de un mes"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"semanas"</string>
<string name="year">"año"</string>
<string name="years">"años"</string>
- <string name="sunday">"Domingo"</string>
- <string name="monday">"Lunes"</string>
- <string name="tuesday">"Martes"</string>
- <string name="wednesday">"Miércoles"</string>
- <string name="thursday">"Jueves"</string>
- <string name="friday">"Viernes"</string>
- <string name="saturday">"Sábado"</string>
<string name="every_weekday">"Todos los días laborables (Lun-Vie)"</string>
<string name="daily">"Diariamente"</string>
<string name="weekly">"Semanalmente, el <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Este vídeo no se puede transmitir al dispositivo."</string>
<string name="VideoView_error_text_unknown">"Este vídeo no se puede reproducir."</string>
<string name="VideoView_error_button">"Aceptar"</string>
- <string name="am">"a.m."</string>
- <string name="pm">"p.m."</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"mediodía"</string>
<string name="Noon">"Mediodía"</string>
<string name="midnight">"medianoche"</string>
<string name="Midnight">"Medianoche"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> de <xliff:g id="MONTH">%b</xliff:g> de <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"Domingo"</string>
- <string name="day_of_week_long_monday">"Lunes"</string>
- <string name="day_of_week_long_tuesday">"Martes"</string>
- <string name="day_of_week_long_wednesday">"Miércoles"</string>
- <string name="day_of_week_long_thursday">"Jueves"</string>
- <string name="day_of_week_long_friday">"Viernes"</string>
- <string name="day_of_week_long_saturday">"Sábado"</string>
- <string name="day_of_week_medium_sunday">"Dom"</string>
- <string name="day_of_week_medium_monday">"Lun"</string>
- <string name="day_of_week_medium_tuesday">"Mar"</string>
- <string name="day_of_week_medium_wednesday">"Mié"</string>
- <string name="day_of_week_medium_thursday">"Jue"</string>
- <string name="day_of_week_medium_friday">"Vie"</string>
- <string name="day_of_week_medium_saturday">"Sáb"</string>
- <string name="day_of_week_short_sunday">"Do"</string>
- <string name="day_of_week_short_monday">"Lu"</string>
- <string name="day_of_week_short_tuesday">"Ma"</string>
- <string name="day_of_week_short_wednesday">"Mi"</string>
- <string name="day_of_week_short_thursday">"Ju"</string>
- <string name="day_of_week_short_friday">"Vi"</string>
- <string name="day_of_week_short_saturday">"Sá"</string>
- <string name="day_of_week_shorter_sunday">"Do"</string>
- <string name="day_of_week_shorter_monday">"L"</string>
- <string name="day_of_week_shorter_tuesday">"Ma"</string>
- <string name="day_of_week_shorter_wednesday">"Mi"</string>
- <string name="day_of_week_shorter_thursday">"Ju"</string>
- <string name="day_of_week_shorter_friday">"V"</string>
- <string name="day_of_week_shorter_saturday">"S"</string>
- <string name="day_of_week_shortest_sunday">"D"</string>
- <string name="day_of_week_shortest_monday">"Mz"</string>
- <string name="day_of_week_shortest_tuesday">"M"</string>
- <string name="day_of_week_shortest_wednesday">"Mi"</string>
- <string name="day_of_week_shortest_thursday">"M"</string>
- <string name="day_of_week_shortest_friday">"V"</string>
- <string name="day_of_week_shortest_saturday">"D"</string>
- <string name="month_long_january">"Enero"</string>
- <string name="month_long_february">"Febrero"</string>
- <string name="month_long_march">"Marzo"</string>
- <string name="month_long_april">"Abril"</string>
- <string name="month_long_may">"Mayo"</string>
- <string name="month_long_june">"Junio"</string>
- <string name="month_long_july">"Julio"</string>
- <string name="month_long_august">"Agosto"</string>
- <string name="month_long_september">"Septiembre"</string>
- <string name="month_long_october">"Octubre"</string>
- <string name="month_long_november">"Noviembre"</string>
- <string name="month_long_december">"Diciembre"</string>
- <string name="month_medium_january">"Ene"</string>
- <string name="month_medium_february">"Feb"</string>
- <string name="month_medium_march">"Mar"</string>
- <string name="month_medium_april">"Abr"</string>
- <string name="month_medium_may">"May"</string>
- <string name="month_medium_june">"Jun"</string>
- <string name="month_medium_july">"Jul"</string>
- <string name="month_medium_august">"Ago"</string>
- <string name="month_medium_september">"Sep"</string>
- <string name="month_medium_october">"Oct"</string>
- <string name="month_medium_november">"Nov"</string>
- <string name="month_medium_december">"Dic"</string>
- <string name="month_shortest_january">"E"</string>
- <string name="month_shortest_february">"V"</string>
- <string name="month_shortest_march">"Mz"</string>
- <string name="month_shortest_april">"A"</string>
- <string name="month_shortest_may">"My"</string>
- <string name="month_shortest_june">"J"</string>
- <string name="month_shortest_july">"E"</string>
- <string name="month_shortest_august">"Ag"</string>
- <string name="month_shortest_september">"S"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"D"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Seleccionar todo"</string>
diff --git a/core/res/res/values-fi-rFI/donottranslate-cldr.xml b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
new file mode 100644
index 0000000..ae28635
--- /dev/null
+++ b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">tammikuu</string>
+ <string name="month_long_standalone_february">helmikuu</string>
+ <string name="month_long_standalone_march">maaliskuu</string>
+ <string name="month_long_standalone_april">huhtikuu</string>
+ <string name="month_long_standalone_may">toukokuu</string>
+ <string name="month_long_standalone_june">kesäkuu</string>
+ <string name="month_long_standalone_july">heinäkuu</string>
+ <string name="month_long_standalone_august">elokuu</string>
+ <string name="month_long_standalone_september">syyskuu</string>
+ <string name="month_long_standalone_october">lokakuu</string>
+ <string name="month_long_standalone_november">marraskuu</string>
+ <string name="month_long_standalone_december">joulukuu</string>
+
+ <string name="month_long_january">tammikuuta</string>
+ <string name="month_long_february">helmikuuta</string>
+ <string name="month_long_march">maaliskuuta</string>
+ <string name="month_long_april">huhtikuuta</string>
+ <string name="month_long_may">toukokuuta</string>
+ <string name="month_long_june">kesäkuuta</string>
+ <string name="month_long_july">heinäkuuta</string>
+ <string name="month_long_august">elokuuta</string>
+ <string name="month_long_september">syyskuuta</string>
+ <string name="month_long_october">lokakuuta</string>
+ <string name="month_long_november">marraskuuta</string>
+ <string name="month_long_december">joulukuuta</string>
+
+ <string name="month_medium_january">tammikuuta</string>
+ <string name="month_medium_february">helmikuuta</string>
+ <string name="month_medium_march">maaliskuuta</string>
+ <string name="month_medium_april">huhtikuuta</string>
+ <string name="month_medium_may">toukokuuta</string>
+ <string name="month_medium_june">kesäkuuta</string>
+ <string name="month_medium_july">heinäkuuta</string>
+ <string name="month_medium_august">elokuuta</string>
+ <string name="month_medium_september">syyskuuta</string>
+ <string name="month_medium_october">lokakuuta</string>
+ <string name="month_medium_november">marraskuuta</string>
+ <string name="month_medium_december">joulukuuta</string>
+
+ <string name="month_shortest_january">T</string>
+ <string name="month_shortest_february">H</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">H</string>
+ <string name="month_shortest_may">T</string>
+ <string name="month_shortest_june">K</string>
+ <string name="month_shortest_july">H</string>
+ <string name="month_shortest_august">E</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">L</string>
+ <string name="month_shortest_november">M</string>
+ <string name="month_shortest_december">J</string>
+
+ <string name="day_of_week_long_sunday">sunnuntaina</string>
+ <string name="day_of_week_long_monday">maanantaina</string>
+ <string name="day_of_week_long_tuesday">tiistaina</string>
+ <string name="day_of_week_long_wednesday">keskiviikkona</string>
+ <string name="day_of_week_long_thursday">torstaina</string>
+ <string name="day_of_week_long_friday">perjantaina</string>
+ <string name="day_of_week_long_saturday">lauantaina</string>
+
+ <string name="day_of_week_medium_sunday">su</string>
+ <string name="day_of_week_medium_monday">ma</string>
+ <string name="day_of_week_medium_tuesday">ti</string>
+ <string name="day_of_week_medium_wednesday">ke</string>
+ <string name="day_of_week_medium_thursday">to</string>
+ <string name="day_of_week_medium_friday">pe</string>
+ <string name="day_of_week_medium_saturday">la</string>
+
+ <string name="day_of_week_short_sunday">su</string>
+ <string name="day_of_week_short_monday">ma</string>
+ <string name="day_of_week_short_tuesday">ti</string>
+ <string name="day_of_week_short_wednesday">ke</string>
+ <string name="day_of_week_short_thursday">to</string>
+ <string name="day_of_week_short_friday">pe</string>
+ <string name="day_of_week_short_saturday">la</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">K</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">L</string>
+
+ <string name="am">ap.</string>
+ <string name="pm">ip.</string>
+ <string name="yesterday">eilen</string>
+ <string name="today">tänään</string>
+ <string name="tomorrow">huomenna</string>
+
+ <string name="hour_minute_ampm">%-k.%M</string>
+ <string name="hour_minute_cap_ampm">%-k.%M</string>
+ <string name="numeric_date">%-e.%-m.%Y</string>
+ <string name="numeric_date_format">d.M.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%-k.%M.%S</string>
+ <string name="date_and_time">%-k.%M.%S %-e.%-m.%Y</string>
+ <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%-b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr-rBE/donottranslate-cldr.xml b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
new file mode 100644
index 0000000..b540336
--- /dev/null
+++ b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvier</string>
+ <string name="month_long_standalone_february">février</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avril</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juin</string>
+ <string name="month_long_standalone_july">juillet</string>
+ <string name="month_long_standalone_august">août</string>
+ <string name="month_long_standalone_september">septembre</string>
+ <string name="month_long_standalone_october">octobre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">décembre</string>
+
+ <string name="month_long_january">janvier</string>
+ <string name="month_long_february">février</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avril</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juin</string>
+ <string name="month_long_july">juillet</string>
+ <string name="month_long_august">août</string>
+ <string name="month_long_september">septembre</string>
+ <string name="month_long_october">octobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">décembre</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">févr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juin</string>
+ <string name="month_medium_july">juil.</string>
+ <string name="month_medium_august">août</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">déc.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">dimanche</string>
+ <string name="day_of_week_long_monday">lundi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mercredi</string>
+ <string name="day_of_week_long_thursday">jeudi</string>
+ <string name="day_of_week_long_friday">vendredi</string>
+ <string name="day_of_week_long_saturday">samedi</string>
+
+ <string name="day_of_week_medium_sunday">dim.</string>
+ <string name="day_of_week_medium_monday">lun.</string>
+ <string name="day_of_week_medium_tuesday">mar.</string>
+ <string name="day_of_week_medium_wednesday">mer.</string>
+ <string name="day_of_week_medium_thursday">jeu.</string>
+ <string name="day_of_week_medium_friday">ven.</string>
+ <string name="day_of_week_medium_saturday">sam.</string>
+
+ <string name="day_of_week_short_sunday">dim.</string>
+ <string name="day_of_week_short_monday">lun.</string>
+ <string name="day_of_week_short_tuesday">mar.</string>
+ <string name="day_of_week_short_wednesday">mer.</string>
+ <string name="day_of_week_short_thursday">jeu.</string>
+ <string name="day_of_week_short_friday">ven.</string>
+ <string name="day_of_week_short_saturday">sam.</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">matin</string>
+ <string name="pm">soir</string>
+ <string name="yesterday">hier</string>
+ <string name="today">aujourd’hui</string>
+ <string name="tomorrow">demain</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%-e/%m/%Y</string>
+ <string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr-rCA/donottranslate-cldr.xml b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
new file mode 100644
index 0000000..5fa5d54
--- /dev/null
+++ b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvier</string>
+ <string name="month_long_standalone_february">février</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avril</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juin</string>
+ <string name="month_long_standalone_july">juillet</string>
+ <string name="month_long_standalone_august">août</string>
+ <string name="month_long_standalone_september">septembre</string>
+ <string name="month_long_standalone_october">octobre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">décembre</string>
+
+ <string name="month_long_january">janvier</string>
+ <string name="month_long_february">février</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avril</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juin</string>
+ <string name="month_long_july">juillet</string>
+ <string name="month_long_august">août</string>
+ <string name="month_long_september">septembre</string>
+ <string name="month_long_october">octobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">décembre</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">févr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juin</string>
+ <string name="month_medium_july">juil.</string>
+ <string name="month_medium_august">août</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">déc.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">dimanche</string>
+ <string name="day_of_week_long_monday">lundi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mercredi</string>
+ <string name="day_of_week_long_thursday">jeudi</string>
+ <string name="day_of_week_long_friday">vendredi</string>
+ <string name="day_of_week_long_saturday">samedi</string>
+
+ <string name="day_of_week_medium_sunday">dim.</string>
+ <string name="day_of_week_medium_monday">lun.</string>
+ <string name="day_of_week_medium_tuesday">mar.</string>
+ <string name="day_of_week_medium_wednesday">mer.</string>
+ <string name="day_of_week_medium_thursday">jeu.</string>
+ <string name="day_of_week_medium_friday">ven.</string>
+ <string name="day_of_week_medium_saturday">sam.</string>
+
+ <string name="day_of_week_short_sunday">dim.</string>
+ <string name="day_of_week_short_monday">lun.</string>
+ <string name="day_of_week_short_tuesday">mar.</string>
+ <string name="day_of_week_short_wednesday">mer.</string>
+ <string name="day_of_week_short_thursday">jeu.</string>
+ <string name="day_of_week_short_friday">ven.</string>
+ <string name="day_of_week_short_saturday">sam.</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">matin</string>
+ <string name="pm">soir</string>
+ <string name="yesterday">hier</string>
+ <string name="today">aujourd’hui</string>
+ <string name="tomorrow">demain</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%Y-%m-%d</string>
+ <string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %Y-%m-%d</string>
+ <string name="abbrev_month_day_year">%Y-%m-%d</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr-rCH/donottranslate-cldr.xml b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
new file mode 100644
index 0000000..589c801
--- /dev/null
+++ b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvier</string>
+ <string name="month_long_standalone_february">février</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avril</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juin</string>
+ <string name="month_long_standalone_july">juillet</string>
+ <string name="month_long_standalone_august">août</string>
+ <string name="month_long_standalone_september">septembre</string>
+ <string name="month_long_standalone_october">octobre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">décembre</string>
+
+ <string name="month_long_january">janvier</string>
+ <string name="month_long_february">février</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avril</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juin</string>
+ <string name="month_long_july">juillet</string>
+ <string name="month_long_august">août</string>
+ <string name="month_long_september">septembre</string>
+ <string name="month_long_october">octobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">décembre</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">févr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juin</string>
+ <string name="month_medium_july">juil.</string>
+ <string name="month_medium_august">août</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">déc.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">dimanche</string>
+ <string name="day_of_week_long_monday">lundi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mercredi</string>
+ <string name="day_of_week_long_thursday">jeudi</string>
+ <string name="day_of_week_long_friday">vendredi</string>
+ <string name="day_of_week_long_saturday">samedi</string>
+
+ <string name="day_of_week_medium_sunday">dim.</string>
+ <string name="day_of_week_medium_monday">lun.</string>
+ <string name="day_of_week_medium_tuesday">mar.</string>
+ <string name="day_of_week_medium_wednesday">mer.</string>
+ <string name="day_of_week_medium_thursday">jeu.</string>
+ <string name="day_of_week_medium_friday">ven.</string>
+ <string name="day_of_week_medium_saturday">sam.</string>
+
+ <string name="day_of_week_short_sunday">dim.</string>
+ <string name="day_of_week_short_monday">lun.</string>
+ <string name="day_of_week_short_tuesday">mar.</string>
+ <string name="day_of_week_short_wednesday">mer.</string>
+ <string name="day_of_week_short_thursday">jeu.</string>
+ <string name="day_of_week_short_friday">ven.</string>
+ <string name="day_of_week_short_saturday">sam.</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">matin</string>
+ <string name="pm">soir</string>
+ <string name="yesterday">hier</string>
+ <string name="today">aujourd’hui</string>
+ <string name="tomorrow">demain</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr-rFR/donottranslate-cldr.xml b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
new file mode 100644
index 0000000..1213ed8
--- /dev/null
+++ b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvier</string>
+ <string name="month_long_standalone_february">février</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avril</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juin</string>
+ <string name="month_long_standalone_july">juillet</string>
+ <string name="month_long_standalone_august">août</string>
+ <string name="month_long_standalone_september">septembre</string>
+ <string name="month_long_standalone_october">octobre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">décembre</string>
+
+ <string name="month_long_january">janvier</string>
+ <string name="month_long_february">février</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avril</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juin</string>
+ <string name="month_long_july">juillet</string>
+ <string name="month_long_august">août</string>
+ <string name="month_long_september">septembre</string>
+ <string name="month_long_october">octobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">décembre</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">févr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juin</string>
+ <string name="month_medium_july">juil.</string>
+ <string name="month_medium_august">août</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">déc.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">dimanche</string>
+ <string name="day_of_week_long_monday">lundi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mercredi</string>
+ <string name="day_of_week_long_thursday">jeudi</string>
+ <string name="day_of_week_long_friday">vendredi</string>
+ <string name="day_of_week_long_saturday">samedi</string>
+
+ <string name="day_of_week_medium_sunday">dim.</string>
+ <string name="day_of_week_medium_monday">lun.</string>
+ <string name="day_of_week_medium_tuesday">mar.</string>
+ <string name="day_of_week_medium_wednesday">mer.</string>
+ <string name="day_of_week_medium_thursday">jeu.</string>
+ <string name="day_of_week_medium_friday">ven.</string>
+ <string name="day_of_week_medium_saturday">sam.</string>
+
+ <string name="day_of_week_short_sunday">dim.</string>
+ <string name="day_of_week_short_monday">lun.</string>
+ <string name="day_of_week_short_tuesday">mar.</string>
+ <string name="day_of_week_short_wednesday">mer.</string>
+ <string name="day_of_week_short_thursday">jeu.</string>
+ <string name="day_of_week_short_friday">ven.</string>
+ <string name="day_of_week_short_saturday">sam.</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">matin</string>
+ <string name="pm">soir</string>
+ <string name="yesterday">hier</string>
+ <string name="today">aujourd’hui</string>
+ <string name="tomorrow">demain</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr/donottranslate-cldr.xml b/core/res/res/values-fr/donottranslate-cldr.xml
new file mode 100644
index 0000000..1213ed8
--- /dev/null
+++ b/core/res/res/values-fr/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvier</string>
+ <string name="month_long_standalone_february">février</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">avril</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juin</string>
+ <string name="month_long_standalone_july">juillet</string>
+ <string name="month_long_standalone_august">août</string>
+ <string name="month_long_standalone_september">septembre</string>
+ <string name="month_long_standalone_october">octobre</string>
+ <string name="month_long_standalone_november">novembre</string>
+ <string name="month_long_standalone_december">décembre</string>
+
+ <string name="month_long_january">janvier</string>
+ <string name="month_long_february">février</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">avril</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juin</string>
+ <string name="month_long_july">juillet</string>
+ <string name="month_long_august">août</string>
+ <string name="month_long_september">septembre</string>
+ <string name="month_long_october">octobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">décembre</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">févr.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">avr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juin</string>
+ <string name="month_medium_july">juil.</string>
+ <string name="month_medium_august">août</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">déc.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">dimanche</string>
+ <string name="day_of_week_long_monday">lundi</string>
+ <string name="day_of_week_long_tuesday">mardi</string>
+ <string name="day_of_week_long_wednesday">mercredi</string>
+ <string name="day_of_week_long_thursday">jeudi</string>
+ <string name="day_of_week_long_friday">vendredi</string>
+ <string name="day_of_week_long_saturday">samedi</string>
+
+ <string name="day_of_week_medium_sunday">dim.</string>
+ <string name="day_of_week_medium_monday">lun.</string>
+ <string name="day_of_week_medium_tuesday">mar.</string>
+ <string name="day_of_week_medium_wednesday">mer.</string>
+ <string name="day_of_week_medium_thursday">jeu.</string>
+ <string name="day_of_week_medium_friday">ven.</string>
+ <string name="day_of_week_medium_saturday">sam.</string>
+
+ <string name="day_of_week_short_sunday">dim.</string>
+ <string name="day_of_week_short_monday">lun.</string>
+ <string name="day_of_week_short_tuesday">mar.</string>
+ <string name="day_of_week_short_wednesday">mer.</string>
+ <string name="day_of_week_short_thursday">jeu.</string>
+ <string name="day_of_week_short_friday">ven.</string>
+ <string name="day_of_week_short_saturday">sam.</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">matin</string>
+ <string name="pm">soir</string>
+ <string name="yesterday">hier</string>
+ <string name="today">aujourd’hui</string>
+ <string name="tomorrow">demain</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c664d1a..736caf7 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Mot de passe"</string>
<string name="lockscreen_glogin_submit_button">"Se connecter"</string>
<string name="lockscreen_glogin_invalid_input">"Nom d\'utilisateur ou mot de passe incorrect."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Effacer les notifications"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"entrée"</string>
<string name="menu_delete_shortcut_label">"supprimer"</string>
<string name="search_go">"Rechercher"</string>
- <string name="today">"Aujourd\'hui"</string>
- <string name="yesterday">"Hier"</string>
- <string name="tomorrow">"Demain"</string>
<string name="oneMonthDurationPast">"Il y a 1 mois"</string>
<string name="beforeOneMonthDurationPast">"Il y a plus d\'un mois"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"semaines"</string>
<string name="year">"année"</string>
<string name="years">"années"</string>
- <string name="sunday">"dimanche"</string>
- <string name="monday">"lundi"</string>
- <string name="tuesday">"mardi"</string>
- <string name="wednesday">"mercredi"</string>
- <string name="thursday">"jeudi"</string>
- <string name="friday">"vendredi"</string>
- <string name="saturday">"samedi"</string>
<string name="every_weekday">"Tous les jours ouvrés (lun.- ven.)"</string>
<string name="daily">"Tous les jours"</string>
<string name="weekly">"Toutes les semaines le <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Désolé, cette vidéo ne peut être lue sur cet appareil."</string>
<string name="VideoView_error_text_unknown">"Désolé, impossible de lire cette vidéo."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"midi"</string>
<string name="Noon">"Midi"</string>
<string name="midnight">"minuit"</string>
<string name="Midnight">"Minuit"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"dimanche"</string>
- <string name="day_of_week_long_monday">"lundi"</string>
- <string name="day_of_week_long_tuesday">"mardi"</string>
- <string name="day_of_week_long_wednesday">"mercredi"</string>
- <string name="day_of_week_long_thursday">"jeudi"</string>
- <string name="day_of_week_long_friday">"vendredi"</string>
- <string name="day_of_week_long_saturday">"samedi"</string>
- <string name="day_of_week_medium_sunday">"dim."</string>
- <string name="day_of_week_medium_monday">"Lun"</string>
- <string name="day_of_week_medium_tuesday">"Mar"</string>
- <string name="day_of_week_medium_wednesday">"Mer"</string>
- <string name="day_of_week_medium_thursday">"Jeu"</string>
- <string name="day_of_week_medium_friday">"Ven"</string>
- <string name="day_of_week_medium_saturday">"Sam"</string>
- <string name="day_of_week_short_sunday">"Dim"</string>
- <string name="day_of_week_short_monday">"Lun"</string>
- <string name="day_of_week_short_tuesday">"Mar"</string>
- <string name="day_of_week_short_wednesday">"Mer"</string>
- <string name="day_of_week_short_thursday">"Jeu"</string>
- <string name="day_of_week_short_friday">"Ven"</string>
- <string name="day_of_week_short_saturday">"Sam"</string>
- <string name="day_of_week_shorter_sunday">"Dim"</string>
- <string name="day_of_week_shorter_monday">"Lun"</string>
- <string name="day_of_week_shorter_tuesday">"Mar"</string>
- <string name="day_of_week_shorter_wednesday">"Mer"</string>
- <string name="day_of_week_shorter_thursday">"Jeu"</string>
- <string name="day_of_week_shorter_friday">"Ven"</string>
- <string name="day_of_week_shorter_saturday">"sam."</string>
- <string name="day_of_week_shortest_sunday">"Dim"</string>
- <string name="day_of_week_shortest_monday">"Lun"</string>
- <string name="day_of_week_shortest_tuesday">"Mar"</string>
- <string name="day_of_week_shortest_wednesday">"Mer"</string>
- <string name="day_of_week_shortest_thursday">"Jeu"</string>
- <string name="day_of_week_shortest_friday">"Ven"</string>
- <string name="day_of_week_shortest_saturday">"Sam"</string>
- <string name="month_long_january">"janvier"</string>
- <string name="month_long_february">"février"</string>
- <string name="month_long_march">"mars"</string>
- <string name="month_long_april">"avril"</string>
- <string name="month_long_may">"mai"</string>
- <string name="month_long_june">"juin"</string>
- <string name="month_long_july">"juillet"</string>
- <string name="month_long_august">"août"</string>
- <string name="month_long_september">"septembre"</string>
- <string name="month_long_october">"octobre"</string>
- <string name="month_long_november">"novembre"</string>
- <string name="month_long_december">"décembre"</string>
- <string name="month_medium_january">"janv."</string>
- <string name="month_medium_february">"févr."</string>
- <string name="month_medium_march">"mars"</string>
- <string name="month_medium_april">"avr."</string>
- <string name="month_medium_may">"mai"</string>
- <string name="month_medium_june">"juin"</string>
- <string name="month_medium_july">"juil."</string>
- <string name="month_medium_august">"août"</string>
- <string name="month_medium_september">"sept."</string>
- <string name="month_medium_october">"oct."</string>
- <string name="month_medium_november">"nov."</string>
- <string name="month_medium_december">"déc."</string>
- <string name="month_shortest_january">"jan."</string>
- <string name="month_shortest_february">"Ven"</string>
- <string name="month_shortest_march">"mars"</string>
- <string name="month_shortest_april">"avr."</string>
- <string name="month_shortest_may">"mai"</string>
- <string name="month_shortest_june">"juin"</string>
- <string name="month_shortest_july">"juil."</string>
- <string name="month_shortest_august">"août"</string>
- <string name="month_shortest_september">"sept."</string>
- <string name="month_shortest_october">"oct."</string>
- <string name="month_shortest_november">"nov."</string>
- <string name="month_shortest_december">"déc."</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Tout sélectionner"</string>
diff --git a/core/res/res/values-he-rIL/donottranslate-cldr.xml b/core/res/res/values-he-rIL/donottranslate-cldr.xml
new file mode 100644
index 0000000..1b1aafa
--- /dev/null
+++ b/core/res/res/values-he-rIL/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">ינואר</string>
+ <string name="month_long_standalone_february">פברואר</string>
+ <string name="month_long_standalone_march">מרס</string>
+ <string name="month_long_standalone_april">אפריל</string>
+ <string name="month_long_standalone_may">מאי</string>
+ <string name="month_long_standalone_june">יוני</string>
+ <string name="month_long_standalone_july">יולי</string>
+ <string name="month_long_standalone_august">אוגוסט</string>
+ <string name="month_long_standalone_september">ספטמבר</string>
+ <string name="month_long_standalone_october">אוקטובר</string>
+ <string name="month_long_standalone_november">נובמבר</string>
+ <string name="month_long_standalone_december">דצמבר</string>
+
+ <string name="month_long_january">ינואר</string>
+ <string name="month_long_february">פברואר</string>
+ <string name="month_long_march">מרס</string>
+ <string name="month_long_april">אפריל</string>
+ <string name="month_long_may">מאי</string>
+ <string name="month_long_june">יוני</string>
+ <string name="month_long_july">יולי</string>
+ <string name="month_long_august">אוגוסט</string>
+ <string name="month_long_september">ספטמבר</string>
+ <string name="month_long_october">אוקטובר</string>
+ <string name="month_long_november">נובמבר</string>
+ <string name="month_long_december">דצמבר</string>
+
+ <string name="month_medium_january">ינו</string>
+ <string name="month_medium_february">פבר</string>
+ <string name="month_medium_march">מרס</string>
+ <string name="month_medium_april">אפר</string>
+ <string name="month_medium_may">מאי</string>
+ <string name="month_medium_june">יונ</string>
+ <string name="month_medium_july">יול</string>
+ <string name="month_medium_august">אוג</string>
+ <string name="month_medium_september">ספט</string>
+ <string name="month_medium_october">אוק</string>
+ <string name="month_medium_november">נוב</string>
+ <string name="month_medium_december">דצמ</string>
+
+ <string name="month_shortest_january">1</string>
+ <string name="month_shortest_february">2</string>
+ <string name="month_shortest_march">3</string>
+ <string name="month_shortest_april">4</string>
+ <string name="month_shortest_may">5</string>
+ <string name="month_shortest_june">6</string>
+ <string name="month_shortest_july">7</string>
+ <string name="month_shortest_august">8</string>
+ <string name="month_shortest_september">9</string>
+ <string name="month_shortest_october">10</string>
+ <string name="month_shortest_november">11</string>
+ <string name="month_shortest_december">12</string>
+
+ <string name="day_of_week_long_sunday">יום ראשון</string>
+ <string name="day_of_week_long_monday">יום שני</string>
+ <string name="day_of_week_long_tuesday">יום שלישי</string>
+ <string name="day_of_week_long_wednesday">יום רביעי</string>
+ <string name="day_of_week_long_thursday">יום חמישי</string>
+ <string name="day_of_week_long_friday">יום שישי</string>
+ <string name="day_of_week_long_saturday">יום שבת</string>
+
+ <string name="day_of_week_medium_sunday">יום א'</string>
+ <string name="day_of_week_medium_monday">יום ב'</string>
+ <string name="day_of_week_medium_tuesday">יום ג'</string>
+ <string name="day_of_week_medium_wednesday">יום ד'</string>
+ <string name="day_of_week_medium_thursday">יום ה'</string>
+ <string name="day_of_week_medium_friday">יום ו'</string>
+ <string name="day_of_week_medium_saturday">שבת</string>
+
+ <string name="day_of_week_short_sunday">יום א'</string>
+ <string name="day_of_week_short_monday">יום ב'</string>
+ <string name="day_of_week_short_tuesday">יום ג'</string>
+ <string name="day_of_week_short_wednesday">יום ד'</string>
+ <string name="day_of_week_short_thursday">יום ה'</string>
+ <string name="day_of_week_short_friday">יום ו'</string>
+ <string name="day_of_week_short_saturday">שבת</string>
+
+ <string name="day_of_week_shortest_sunday">א</string>
+ <string name="day_of_week_shortest_monday">ב</string>
+ <string name="day_of_week_shortest_tuesday">ג</string>
+ <string name="day_of_week_shortest_wednesday">ד</string>
+ <string name="day_of_week_shortest_thursday">ה</string>
+ <string name="day_of_week_shortest_friday">ו</string>
+ <string name="day_of_week_shortest_saturday">ש</string>
+
+ <string name="am">לפנה"צ</string>
+ <string name="pm">אחה"צ</string>
+ <string name="yesterday">אתמול</string>
+ <string name="today">היום</string>
+ <string name="tomorrow">מחר</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e ב%B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e.%-m.%Y</string>
+ <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+ <string name="month_day">%-e ב%B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-hi-rIN/donottranslate-cldr.xml b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
new file mode 100644
index 0000000..8c6a34f7
--- /dev/null
+++ b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">जनवरी</string>
+ <string name="month_long_standalone_february">फरवरी</string>
+ <string name="month_long_standalone_march">मार्च</string>
+ <string name="month_long_standalone_april">अप्रैल</string>
+ <string name="month_long_standalone_may">मई</string>
+ <string name="month_long_standalone_june">जून</string>
+ <string name="month_long_standalone_july">जुलाई</string>
+ <string name="month_long_standalone_august">अगस्त</string>
+ <string name="month_long_standalone_september">सितम्बर</string>
+ <string name="month_long_standalone_october">अक्तूबर</string>
+ <string name="month_long_standalone_november">नवम्बर</string>
+ <string name="month_long_standalone_december">दिसम्बर</string>
+
+ <string name="month_long_january">जनवरी</string>
+ <string name="month_long_february">फरवरी</string>
+ <string name="month_long_march">मार्च</string>
+ <string name="month_long_april">अप्रैल</string>
+ <string name="month_long_may">मई</string>
+ <string name="month_long_june">जून</string>
+ <string name="month_long_july">जुलाई</string>
+ <string name="month_long_august">अगस्त</string>
+ <string name="month_long_september">सितम्बर</string>
+ <string name="month_long_october">अक्तूबर</string>
+ <string name="month_long_november">नवम्बर</string>
+ <string name="month_long_december">दिसम्बर</string>
+
+ <string name="month_medium_january">जनवरी</string>
+ <string name="month_medium_february">फरवरी</string>
+ <string name="month_medium_march">मार्च</string>
+ <string name="month_medium_april">अप्रैल</string>
+ <string name="month_medium_may">मई</string>
+ <string name="month_medium_june">जून</string>
+ <string name="month_medium_july">जुलाई</string>
+ <string name="month_medium_august">अगस्त</string>
+ <string name="month_medium_september">सितम्बर</string>
+ <string name="month_medium_october">अक्तूबर</string>
+ <string name="month_medium_november">नवम्बर</string>
+ <string name="month_medium_december">दिसम्बर</string>
+
+ <string name="month_shortest_january">ज</string>
+ <string name="month_shortest_february">फ़</string>
+ <string name="month_shortest_march">मा</string>
+ <string name="month_shortest_april">अ</string>
+ <string name="month_shortest_may">म</string>
+ <string name="month_shortest_june">जू</string>
+ <string name="month_shortest_july">जु</string>
+ <string name="month_shortest_august">अ</string>
+ <string name="month_shortest_september">सि</string>
+ <string name="month_shortest_october">अ</string>
+ <string name="month_shortest_november">न</string>
+ <string name="month_shortest_december">दि</string>
+
+ <string name="day_of_week_long_sunday">रविवार</string>
+ <string name="day_of_week_long_monday">सोमवार</string>
+ <string name="day_of_week_long_tuesday">मंगलवार</string>
+ <string name="day_of_week_long_wednesday">बुधवार</string>
+ <string name="day_of_week_long_thursday">गुरुवार</string>
+ <string name="day_of_week_long_friday">शुक्रवार</string>
+ <string name="day_of_week_long_saturday">शनिवार</string>
+
+ <string name="day_of_week_medium_sunday">रवि</string>
+ <string name="day_of_week_medium_monday">सोम</string>
+ <string name="day_of_week_medium_tuesday">मंगल</string>
+ <string name="day_of_week_medium_wednesday">बुध</string>
+ <string name="day_of_week_medium_thursday">गुरु</string>
+ <string name="day_of_week_medium_friday">शुक्र</string>
+ <string name="day_of_week_medium_saturday">शनि</string>
+
+ <string name="day_of_week_short_sunday">रवि</string>
+ <string name="day_of_week_short_monday">सोम</string>
+ <string name="day_of_week_short_tuesday">मंगल</string>
+ <string name="day_of_week_short_wednesday">बुध</string>
+ <string name="day_of_week_short_thursday">गुरु</string>
+ <string name="day_of_week_short_friday">शुक्र</string>
+ <string name="day_of_week_short_saturday">शनि</string>
+
+ <string name="day_of_week_shortest_sunday">र</string>
+ <string name="day_of_week_shortest_monday">सो</string>
+ <string name="day_of_week_shortest_tuesday">मं</string>
+ <string name="day_of_week_shortest_wednesday">बु</string>
+ <string name="day_of_week_shortest_thursday">गु</string>
+ <string name="day_of_week_shortest_friday">शु</string>
+ <string name="day_of_week_shortest_saturday">श</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-e-%-m-%Y</string>
+ <string name="numeric_date_format">d-M-yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %d-%m-%Y</string>
+ <string name="abbrev_month_day_year">%d-%m-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-hu-rHU/donottranslate-cldr.xml b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
new file mode 100644
index 0000000..6085c6f
--- /dev/null
+++ b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">január</string>
+ <string name="month_long_standalone_february">február</string>
+ <string name="month_long_standalone_march">március</string>
+ <string name="month_long_standalone_april">április</string>
+ <string name="month_long_standalone_may">május</string>
+ <string name="month_long_standalone_june">június</string>
+ <string name="month_long_standalone_july">július</string>
+ <string name="month_long_standalone_august">augusztus</string>
+ <string name="month_long_standalone_september">szeptember</string>
+ <string name="month_long_standalone_october">október</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">január</string>
+ <string name="month_long_february">február</string>
+ <string name="month_long_march">március</string>
+ <string name="month_long_april">április</string>
+ <string name="month_long_may">május</string>
+ <string name="month_long_june">június</string>
+ <string name="month_long_july">július</string>
+ <string name="month_long_august">augusztus</string>
+ <string name="month_long_september">szeptember</string>
+ <string name="month_long_october">október</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">febr.</string>
+ <string name="month_medium_march">márc.</string>
+ <string name="month_medium_april">ápr.</string>
+ <string name="month_medium_may">máj.</string>
+ <string name="month_medium_june">jún.</string>
+ <string name="month_medium_july">júl.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">szept.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">Á</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">vasárnap</string>
+ <string name="day_of_week_long_monday">hétfő</string>
+ <string name="day_of_week_long_tuesday">kedd</string>
+ <string name="day_of_week_long_wednesday">szerda</string>
+ <string name="day_of_week_long_thursday">csütörtök</string>
+ <string name="day_of_week_long_friday">péntek</string>
+ <string name="day_of_week_long_saturday">szombat</string>
+
+ <string name="day_of_week_medium_sunday">V</string>
+ <string name="day_of_week_medium_monday">H</string>
+ <string name="day_of_week_medium_tuesday">K</string>
+ <string name="day_of_week_medium_wednesday">Sze</string>
+ <string name="day_of_week_medium_thursday">Cs</string>
+ <string name="day_of_week_medium_friday">P</string>
+ <string name="day_of_week_medium_saturday">Szo</string>
+
+ <string name="day_of_week_short_sunday">V</string>
+ <string name="day_of_week_short_monday">H</string>
+ <string name="day_of_week_short_tuesday">K</string>
+ <string name="day_of_week_short_wednesday">Sze</string>
+ <string name="day_of_week_short_thursday">Cs</string>
+ <string name="day_of_week_short_friday">P</string>
+ <string name="day_of_week_short_saturday">Szo</string>
+
+ <string name="day_of_week_shortest_sunday">V</string>
+ <string name="day_of_week_shortest_monday">H</string>
+ <string name="day_of_week_shortest_tuesday">K</string>
+ <string name="day_of_week_shortest_wednesday">S</string>
+ <string name="day_of_week_shortest_thursday">C</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">de.</string>
+ <string name="pm">du.</string>
+ <string name="yesterday">tegnap</string>
+ <string name="today">ma</string>
+ <string name="tomorrow">holnap</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%Y.%m.%d.</string>
+ <string name="numeric_date_format">yyyy.MM.dd.</string>
+ <string name="month_day_year">%Y. %B %-e.</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %Y.%m.%d.</string>
+ <string name="abbrev_month_day_year">%Y.%m.%d.</string>
+ <string name="month_day">%B %-e.</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e.</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-id-rID/donottranslate-cldr.xml b/core/res/res/values-id-rID/donottranslate-cldr.xml
new file mode 100644
index 0000000..0a15fed
--- /dev/null
+++ b/core/res/res/values-id-rID/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Januari</string>
+ <string name="month_long_standalone_february">Februari</string>
+ <string name="month_long_standalone_march">Maret</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">Mei</string>
+ <string name="month_long_standalone_june">Juni</string>
+ <string name="month_long_standalone_july">Juli</string>
+ <string name="month_long_standalone_august">Agustus</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">Oktober</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">Desember</string>
+
+ <string name="month_long_january">Januari</string>
+ <string name="month_long_february">Februari</string>
+ <string name="month_long_march">Maret</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">Mei</string>
+ <string name="month_long_june">Juni</string>
+ <string name="month_long_july">Juli</string>
+ <string name="month_long_august">Agustus</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">Oktober</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">Desember</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">Mei</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Agu</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Okt</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Des</string>
+
+ <string name="month_shortest_january">1</string>
+ <string name="month_shortest_february">2</string>
+ <string name="month_shortest_march">3</string>
+ <string name="month_shortest_april">4</string>
+ <string name="month_shortest_may">5</string>
+ <string name="month_shortest_june">6</string>
+ <string name="month_shortest_july">7</string>
+ <string name="month_shortest_august">8</string>
+ <string name="month_shortest_september">9</string>
+ <string name="month_shortest_october">10</string>
+ <string name="month_shortest_november">11</string>
+ <string name="month_shortest_december">12</string>
+
+ <string name="day_of_week_long_sunday">Minggu</string>
+ <string name="day_of_week_long_monday">Senin</string>
+ <string name="day_of_week_long_tuesday">Selasa</string>
+ <string name="day_of_week_long_wednesday">Rabu</string>
+ <string name="day_of_week_long_thursday">Kamis</string>
+ <string name="day_of_week_long_friday">Jumat</string>
+ <string name="day_of_week_long_saturday">Sabtu</string>
+
+ <string name="day_of_week_medium_sunday">Min</string>
+ <string name="day_of_week_medium_monday">Sen</string>
+ <string name="day_of_week_medium_tuesday">Sel</string>
+ <string name="day_of_week_medium_wednesday">Rab</string>
+ <string name="day_of_week_medium_thursday">Kam</string>
+ <string name="day_of_week_medium_friday">Jum</string>
+ <string name="day_of_week_medium_saturday">Sab</string>
+
+ <string name="day_of_week_short_sunday">Min</string>
+ <string name="day_of_week_short_monday">Sen</string>
+ <string name="day_of_week_short_tuesday">Sel</string>
+ <string name="day_of_week_short_wednesday">Rab</string>
+ <string name="day_of_week_short_thursday">Kam</string>
+ <string name="day_of_week_short_friday">Jum</string>
+ <string name="day_of_week_short_saturday">Sab</string>
+
+ <string name="day_of_week_shortest_sunday">1</string>
+ <string name="day_of_week_shortest_monday">2</string>
+ <string name="day_of_week_shortest_tuesday">3</string>
+ <string name="day_of_week_shortest_wednesday">4</string>
+ <string name="day_of_week_shortest_thursday">5</string>
+ <string name="day_of_week_shortest_friday">6</string>
+ <string name="day_of_week_shortest_saturday">7</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-it-rCH/donottranslate-cldr.xml b/core/res/res/values-it-rCH/donottranslate-cldr.xml
new file mode 100644
index 0000000..4129d6c
--- /dev/null
+++ b/core/res/res/values-it-rCH/donottranslate-cldr.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Gennaio</string>
+ <string name="month_long_standalone_february">Febbraio</string>
+ <string name="month_long_standalone_march">Marzo</string>
+ <string name="month_long_standalone_april">Aprile</string>
+ <string name="month_long_standalone_may">Maggio</string>
+ <string name="month_long_standalone_june">Giugno</string>
+ <string name="month_long_standalone_july">Luglio</string>
+
+ <string name="month_long_january">gennaio</string>
+ <string name="month_long_february">febbraio</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">aprile</string>
+ <string name="month_long_may">maggio</string>
+ <string name="month_long_june">giugno</string>
+ <string name="month_long_july">Luglio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">settembre</string>
+ <string name="month_long_october">ottobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">dicembre</string>
+
+ <string name="month_medium_january">gen</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">mag</string>
+ <string name="month_medium_june">giu</string>
+ <string name="month_medium_july">lug</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">set</string>
+ <string name="month_medium_october">ott</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">G</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">G</string>
+ <string name="month_shortest_july">L</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domenica</string>
+ <string name="day_of_week_long_monday">lunedì</string>
+ <string name="day_of_week_long_tuesday">martedì</string>
+ <string name="day_of_week_long_wednesday">mercoledì</string>
+ <string name="day_of_week_long_thursday">giovedì</string>
+ <string name="day_of_week_long_friday">venerdì</string>
+ <string name="day_of_week_long_saturday">sabato</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mer</string>
+ <string name="day_of_week_medium_thursday">gio</string>
+ <string name="day_of_week_medium_friday">ven</string>
+ <string name="day_of_week_medium_saturday">sab</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mer</string>
+ <string name="day_of_week_short_thursday">gio</string>
+ <string name="day_of_week_short_friday">ven</string>
+ <string name="day_of_week_short_saturday">sab</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">G</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">m.</string>
+ <string name="pm">p.</string>
+ <string name="yesterday">ieri</string>
+ <string name="today">oggi</string>
+ <string name="tomorrow">domani</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %-e-%b-%Y</string>
+ <string name="abbrev_month_day_year">%-e-%b-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-it-rIT/donottranslate-cldr.xml b/core/res/res/values-it-rIT/donottranslate-cldr.xml
new file mode 100644
index 0000000..e3dd747
--- /dev/null
+++ b/core/res/res/values-it-rIT/donottranslate-cldr.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Gennaio</string>
+ <string name="month_long_standalone_february">Febbraio</string>
+ <string name="month_long_standalone_march">Marzo</string>
+ <string name="month_long_standalone_april">Aprile</string>
+ <string name="month_long_standalone_may">Maggio</string>
+ <string name="month_long_standalone_june">Giugno</string>
+ <string name="month_long_standalone_july">Luglio</string>
+
+ <string name="month_long_january">gennaio</string>
+ <string name="month_long_february">febbraio</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">aprile</string>
+ <string name="month_long_may">maggio</string>
+ <string name="month_long_june">giugno</string>
+ <string name="month_long_july">Luglio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">settembre</string>
+ <string name="month_long_october">ottobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">dicembre</string>
+
+ <string name="month_medium_january">gen</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">mag</string>
+ <string name="month_medium_june">giu</string>
+ <string name="month_medium_july">lug</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">set</string>
+ <string name="month_medium_october">ott</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">G</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">G</string>
+ <string name="month_shortest_july">L</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domenica</string>
+ <string name="day_of_week_long_monday">lunedì</string>
+ <string name="day_of_week_long_tuesday">martedì</string>
+ <string name="day_of_week_long_wednesday">mercoledì</string>
+ <string name="day_of_week_long_thursday">giovedì</string>
+ <string name="day_of_week_long_friday">venerdì</string>
+ <string name="day_of_week_long_saturday">sabato</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mer</string>
+ <string name="day_of_week_medium_thursday">gio</string>
+ <string name="day_of_week_medium_friday">ven</string>
+ <string name="day_of_week_medium_saturday">sab</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mer</string>
+ <string name="day_of_week_short_thursday">gio</string>
+ <string name="day_of_week_short_friday">ven</string>
+ <string name="day_of_week_short_saturday">sab</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">G</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">m.</string>
+ <string name="pm">p.</string>
+ <string name="yesterday">ieri</string>
+ <string name="today">oggi</string>
+ <string name="tomorrow">domani</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %d/%b/%Y</string>
+ <string name="abbrev_month_day_year">%d/%b/%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-it/donottranslate-cldr.xml b/core/res/res/values-it/donottranslate-cldr.xml
new file mode 100644
index 0000000..e3dd747
--- /dev/null
+++ b/core/res/res/values-it/donottranslate-cldr.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Gennaio</string>
+ <string name="month_long_standalone_february">Febbraio</string>
+ <string name="month_long_standalone_march">Marzo</string>
+ <string name="month_long_standalone_april">Aprile</string>
+ <string name="month_long_standalone_may">Maggio</string>
+ <string name="month_long_standalone_june">Giugno</string>
+ <string name="month_long_standalone_july">Luglio</string>
+
+ <string name="month_long_january">gennaio</string>
+ <string name="month_long_february">febbraio</string>
+ <string name="month_long_march">marzo</string>
+ <string name="month_long_april">aprile</string>
+ <string name="month_long_may">maggio</string>
+ <string name="month_long_june">giugno</string>
+ <string name="month_long_july">Luglio</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">settembre</string>
+ <string name="month_long_october">ottobre</string>
+ <string name="month_long_november">novembre</string>
+ <string name="month_long_december">dicembre</string>
+
+ <string name="month_medium_january">gen</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">mag</string>
+ <string name="month_medium_june">giu</string>
+ <string name="month_medium_july">lug</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">set</string>
+ <string name="month_medium_october">ott</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dic</string>
+
+ <string name="month_shortest_january">G</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">G</string>
+ <string name="month_shortest_july">L</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domenica</string>
+ <string name="day_of_week_long_monday">lunedì</string>
+ <string name="day_of_week_long_tuesday">martedì</string>
+ <string name="day_of_week_long_wednesday">mercoledì</string>
+ <string name="day_of_week_long_thursday">giovedì</string>
+ <string name="day_of_week_long_friday">venerdì</string>
+ <string name="day_of_week_long_saturday">sabato</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">lun</string>
+ <string name="day_of_week_medium_tuesday">mar</string>
+ <string name="day_of_week_medium_wednesday">mer</string>
+ <string name="day_of_week_medium_thursday">gio</string>
+ <string name="day_of_week_medium_friday">ven</string>
+ <string name="day_of_week_medium_saturday">sab</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">lun</string>
+ <string name="day_of_week_short_tuesday">mar</string>
+ <string name="day_of_week_short_wednesday">mer</string>
+ <string name="day_of_week_short_thursday">gio</string>
+ <string name="day_of_week_short_friday">ven</string>
+ <string name="day_of_week_short_saturday">sab</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">G</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">m.</string>
+ <string name="pm">p.</string>
+ <string name="yesterday">ieri</string>
+ <string name="today">oggi</string>
+ <string name="tomorrow">domani</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %d/%b/%Y</string>
+ <string name="abbrev_month_day_year">%d/%b/%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f80a4f4..cb040f2 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Password"</string>
<string name="lockscreen_glogin_submit_button">"Accedi"</string>
<string name="lockscreen_glogin_invalid_input">"Password o nome utente non valido."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Cancella notifiche"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"Invio"</string>
<string name="menu_delete_shortcut_label">"Canc"</string>
<string name="search_go">"Cerca"</string>
- <string name="today">"Oggi"</string>
- <string name="yesterday">"Ieri"</string>
- <string name="tomorrow">"Domani"</string>
<string name="oneMonthDurationPast">"1 mese fa"</string>
<string name="beforeOneMonthDurationPast">"Oltre 1 mese fa"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"settimane"</string>
<string name="year">"anno"</string>
<string name="years">"anni"</string>
- <string name="sunday">"Domenica"</string>
- <string name="monday">"Lunedì"</string>
- <string name="tuesday">"Martedì"</string>
- <string name="wednesday">"Mercoledì"</string>
- <string name="thursday">"Giovedì"</string>
- <string name="friday">"Venerdì"</string>
- <string name="saturday">"Sabato"</string>
<string name="every_weekday">"Ogni giorno feriale (lun-ven)"</string>
<string name="daily">"Quotidianamente"</string>
<string name="weekly">"Ogni settimana il <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Spiacenti, questo video non è valido per lo streaming su questo dispositivo."</string>
<string name="VideoView_error_text_unknown">"Spiacenti. Impossibile riprodurre il video."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"mezzogiorno"</string>
<string name="Noon">"Mezzogiorno"</string>
<string name="midnight">"mezzanotte"</string>
<string name="Midnight">"Mezzanotte"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"Domenica"</string>
- <string name="day_of_week_long_monday">"Lunedì"</string>
- <string name="day_of_week_long_tuesday">"Martedì"</string>
- <string name="day_of_week_long_wednesday">"Mercoledì"</string>
- <string name="day_of_week_long_thursday">"Giovedì"</string>
- <string name="day_of_week_long_friday">"Venerdì"</string>
- <string name="day_of_week_long_saturday">"Sabato"</string>
- <string name="day_of_week_medium_sunday">"Dom"</string>
- <string name="day_of_week_medium_monday">"Lun"</string>
- <string name="day_of_week_medium_tuesday">"Mar"</string>
- <string name="day_of_week_medium_wednesday">"Mer"</string>
- <string name="day_of_week_medium_thursday">"Gio"</string>
- <string name="day_of_week_medium_friday">"Ven"</string>
- <string name="day_of_week_medium_saturday">"Sab"</string>
- <string name="day_of_week_short_sunday">"Do"</string>
- <string name="day_of_week_short_monday">"Lu"</string>
- <string name="day_of_week_short_tuesday">"Ma"</string>
- <string name="day_of_week_short_wednesday">"Me"</string>
- <string name="day_of_week_short_thursday">"Gi"</string>
- <string name="day_of_week_short_friday">"Ve"</string>
- <string name="day_of_week_short_saturday">"Sa"</string>
- <string name="day_of_week_shorter_sunday">"Do"</string>
- <string name="day_of_week_shorter_monday">"Lu"</string>
- <string name="day_of_week_shorter_tuesday">"Ma"</string>
- <string name="day_of_week_shorter_wednesday">"Me"</string>
- <string name="day_of_week_shorter_thursday">"Gi"</string>
- <string name="day_of_week_shorter_friday">"V"</string>
- <string name="day_of_week_shorter_saturday">"Sa"</string>
- <string name="day_of_week_shortest_sunday">"D"</string>
- <string name="day_of_week_shortest_monday">"Lun"</string>
- <string name="day_of_week_shortest_tuesday">"M"</string>
- <string name="day_of_week_shortest_wednesday">"Me"</string>
- <string name="day_of_week_shortest_thursday">"G"</string>
- <string name="day_of_week_shortest_friday">"V"</string>
- <string name="day_of_week_shortest_saturday">"Sa"</string>
- <string name="month_long_january">"Gennaio"</string>
- <string name="month_long_february">"Febbraio"</string>
- <string name="month_long_march">"Marzo"</string>
- <string name="month_long_april">"Aprile"</string>
- <string name="month_long_may">"Maggio"</string>
- <string name="month_long_june">"Giugno"</string>
- <string name="month_long_july">"Luglio"</string>
- <string name="month_long_august">"Agosto"</string>
- <string name="month_long_september">"Settembre"</string>
- <string name="month_long_october">"Ottobre"</string>
- <string name="month_long_november">"Novembre"</string>
- <string name="month_long_december">"Dicembre"</string>
- <string name="month_medium_january">"Gen"</string>
- <string name="month_medium_february">"Feb"</string>
- <string name="month_medium_march">"Mar"</string>
- <string name="month_medium_april">"Apr"</string>
- <string name="month_medium_may">"Mag"</string>
- <string name="month_medium_june">"Giu"</string>
- <string name="month_medium_july">"Lug"</string>
- <string name="month_medium_august">"Ago"</string>
- <string name="month_medium_september">"Set"</string>
- <string name="month_medium_october">"Ott"</string>
- <string name="month_medium_november">"Nov"</string>
- <string name="month_medium_december">"Dic"</string>
- <string name="month_shortest_january">"G"</string>
- <string name="month_shortest_february">"F"</string>
- <string name="month_shortest_march">"M"</string>
- <string name="month_shortest_april">"Ap"</string>
- <string name="month_shortest_may">"Mag"</string>
- <string name="month_shortest_june">"Gi"</string>
- <string name="month_shortest_july">"Lug"</string>
- <string name="month_shortest_august">"Ago"</string>
- <string name="month_shortest_september">"Set"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"Di"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Seleziona tutto"</string>
diff --git a/core/res/res/values-ja-rJP/donottranslate-cldr.xml b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
new file mode 100644
index 0000000..b8e94fc
--- /dev/null
+++ b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">1月</string>
+ <string name="month_long_standalone_february">2月</string>
+ <string name="month_long_standalone_march">3月</string>
+ <string name="month_long_standalone_april">4月</string>
+ <string name="month_long_standalone_may">5月</string>
+ <string name="month_long_standalone_june">6月</string>
+ <string name="month_long_standalone_july">7月</string>
+ <string name="month_long_standalone_august">8月</string>
+ <string name="month_long_standalone_september">9月</string>
+ <string name="month_long_standalone_october">10月</string>
+ <string name="month_long_standalone_november">11月</string>
+ <string name="month_long_standalone_december">12月</string>
+
+ <string name="month_long_january">1月</string>
+ <string name="month_long_february">2月</string>
+ <string name="month_long_march">3月</string>
+ <string name="month_long_april">4月</string>
+ <string name="month_long_may">5月</string>
+ <string name="month_long_june">6月</string>
+ <string name="month_long_july">7月</string>
+ <string name="month_long_august">8月</string>
+ <string name="month_long_september">9月</string>
+ <string name="month_long_october">10月</string>
+ <string name="month_long_november">11月</string>
+ <string name="month_long_december">12月</string>
+
+ <string name="month_medium_january">1月</string>
+ <string name="month_medium_february">2月</string>
+ <string name="month_medium_march">3月</string>
+ <string name="month_medium_april">4月</string>
+ <string name="month_medium_may">5月</string>
+ <string name="month_medium_june">6月</string>
+ <string name="month_medium_july">7月</string>
+ <string name="month_medium_august">8月</string>
+ <string name="month_medium_september">9月</string>
+ <string name="month_medium_october">10月</string>
+ <string name="month_medium_november">11月</string>
+ <string name="month_medium_december">12月</string>
+
+ <string name="month_shortest_january">1</string>
+ <string name="month_shortest_february">2</string>
+ <string name="month_shortest_march">3</string>
+ <string name="month_shortest_april">4</string>
+ <string name="month_shortest_may">5</string>
+ <string name="month_shortest_june">6</string>
+ <string name="month_shortest_july">7</string>
+ <string name="month_shortest_august">8</string>
+ <string name="month_shortest_september">9</string>
+ <string name="month_shortest_october">10</string>
+ <string name="month_shortest_november">11</string>
+ <string name="month_shortest_december">12</string>
+
+ <string name="day_of_week_long_sunday">日曜日</string>
+ <string name="day_of_week_long_monday">月曜日</string>
+ <string name="day_of_week_long_tuesday">火曜日</string>
+ <string name="day_of_week_long_wednesday">水曜日</string>
+ <string name="day_of_week_long_thursday">木曜日</string>
+ <string name="day_of_week_long_friday">金曜日</string>
+ <string name="day_of_week_long_saturday">土曜日</string>
+
+ <string name="day_of_week_medium_sunday">日</string>
+ <string name="day_of_week_medium_monday">月</string>
+ <string name="day_of_week_medium_tuesday">火</string>
+ <string name="day_of_week_medium_wednesday">水</string>
+ <string name="day_of_week_medium_thursday">木</string>
+ <string name="day_of_week_medium_friday">金</string>
+ <string name="day_of_week_medium_saturday">土</string>
+
+ <string name="day_of_week_short_sunday">日</string>
+ <string name="day_of_week_short_monday">月</string>
+ <string name="day_of_week_short_tuesday">火</string>
+ <string name="day_of_week_short_wednesday">水</string>
+ <string name="day_of_week_short_thursday">木</string>
+ <string name="day_of_week_short_friday">金</string>
+ <string name="day_of_week_short_saturday">土</string>
+
+ <string name="day_of_week_shortest_sunday">日</string>
+ <string name="day_of_week_shortest_monday">月</string>
+ <string name="day_of_week_shortest_tuesday">火</string>
+ <string name="day_of_week_shortest_wednesday">水</string>
+ <string name="day_of_week_shortest_thursday">木</string>
+ <string name="day_of_week_shortest_friday">金</string>
+ <string name="day_of_week_shortest_saturday">土</string>
+
+ <string name="am">午前</string>
+ <string name="pm">午後</string>
+ <string name="yesterday">昨日</string>
+ <string name="today">今日</string>
+ <string name="tomorrow">明日</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%Y/%m/%d</string>
+ <string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="month_day_year">%Y年%-m月%-e日</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %Y/%m/%d</string>
+ <string name="abbrev_month_day_year">%Y/%m/%d</string>
+ <string name="month_day">%-m月%-e日</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y年%-m月</string>
+ <string name="abbrev_month_day">%-m月%-e日</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y年%-m月</string>
+</resources>
diff --git a/core/res/res/values-ja/donottranslate-cldr.xml b/core/res/res/values-ja/donottranslate-cldr.xml
new file mode 100644
index 0000000..b8e94fc
--- /dev/null
+++ b/core/res/res/values-ja/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">1月</string>
+ <string name="month_long_standalone_february">2月</string>
+ <string name="month_long_standalone_march">3月</string>
+ <string name="month_long_standalone_april">4月</string>
+ <string name="month_long_standalone_may">5月</string>
+ <string name="month_long_standalone_june">6月</string>
+ <string name="month_long_standalone_july">7月</string>
+ <string name="month_long_standalone_august">8月</string>
+ <string name="month_long_standalone_september">9月</string>
+ <string name="month_long_standalone_october">10月</string>
+ <string name="month_long_standalone_november">11月</string>
+ <string name="month_long_standalone_december">12月</string>
+
+ <string name="month_long_january">1月</string>
+ <string name="month_long_february">2月</string>
+ <string name="month_long_march">3月</string>
+ <string name="month_long_april">4月</string>
+ <string name="month_long_may">5月</string>
+ <string name="month_long_june">6月</string>
+ <string name="month_long_july">7月</string>
+ <string name="month_long_august">8月</string>
+ <string name="month_long_september">9月</string>
+ <string name="month_long_october">10月</string>
+ <string name="month_long_november">11月</string>
+ <string name="month_long_december">12月</string>
+
+ <string name="month_medium_january">1月</string>
+ <string name="month_medium_february">2月</string>
+ <string name="month_medium_march">3月</string>
+ <string name="month_medium_april">4月</string>
+ <string name="month_medium_may">5月</string>
+ <string name="month_medium_june">6月</string>
+ <string name="month_medium_july">7月</string>
+ <string name="month_medium_august">8月</string>
+ <string name="month_medium_september">9月</string>
+ <string name="month_medium_october">10月</string>
+ <string name="month_medium_november">11月</string>
+ <string name="month_medium_december">12月</string>
+
+ <string name="month_shortest_january">1</string>
+ <string name="month_shortest_february">2</string>
+ <string name="month_shortest_march">3</string>
+ <string name="month_shortest_april">4</string>
+ <string name="month_shortest_may">5</string>
+ <string name="month_shortest_june">6</string>
+ <string name="month_shortest_july">7</string>
+ <string name="month_shortest_august">8</string>
+ <string name="month_shortest_september">9</string>
+ <string name="month_shortest_october">10</string>
+ <string name="month_shortest_november">11</string>
+ <string name="month_shortest_december">12</string>
+
+ <string name="day_of_week_long_sunday">日曜日</string>
+ <string name="day_of_week_long_monday">月曜日</string>
+ <string name="day_of_week_long_tuesday">火曜日</string>
+ <string name="day_of_week_long_wednesday">水曜日</string>
+ <string name="day_of_week_long_thursday">木曜日</string>
+ <string name="day_of_week_long_friday">金曜日</string>
+ <string name="day_of_week_long_saturday">土曜日</string>
+
+ <string name="day_of_week_medium_sunday">日</string>
+ <string name="day_of_week_medium_monday">月</string>
+ <string name="day_of_week_medium_tuesday">火</string>
+ <string name="day_of_week_medium_wednesday">水</string>
+ <string name="day_of_week_medium_thursday">木</string>
+ <string name="day_of_week_medium_friday">金</string>
+ <string name="day_of_week_medium_saturday">土</string>
+
+ <string name="day_of_week_short_sunday">日</string>
+ <string name="day_of_week_short_monday">月</string>
+ <string name="day_of_week_short_tuesday">火</string>
+ <string name="day_of_week_short_wednesday">水</string>
+ <string name="day_of_week_short_thursday">木</string>
+ <string name="day_of_week_short_friday">金</string>
+ <string name="day_of_week_short_saturday">土</string>
+
+ <string name="day_of_week_shortest_sunday">日</string>
+ <string name="day_of_week_shortest_monday">月</string>
+ <string name="day_of_week_shortest_tuesday">火</string>
+ <string name="day_of_week_shortest_wednesday">水</string>
+ <string name="day_of_week_shortest_thursday">木</string>
+ <string name="day_of_week_shortest_friday">金</string>
+ <string name="day_of_week_shortest_saturday">土</string>
+
+ <string name="am">午前</string>
+ <string name="pm">午後</string>
+ <string name="yesterday">昨日</string>
+ <string name="today">今日</string>
+ <string name="tomorrow">明日</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%Y/%m/%d</string>
+ <string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="month_day_year">%Y年%-m月%-e日</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %Y/%m/%d</string>
+ <string name="abbrev_month_day_year">%Y/%m/%d</string>
+ <string name="month_day">%-m月%-e日</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y年%-m月</string>
+ <string name="abbrev_month_day">%-m月%-e日</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y年%-m月</string>
+</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 8da040e..877ecbd 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"パスワード"</string>
<string name="lockscreen_glogin_submit_button">"ログイン"</string>
<string name="lockscreen_glogin_invalid_input">"ユーザー名またはパスワードが正しくありません。"</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"通知を消去"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"Enter"</string>
<string name="menu_delete_shortcut_label">"Del"</string>
<string name="search_go">"検索"</string>
- <string name="today">"今日"</string>
- <string name="yesterday">"昨日"</string>
- <string name="tomorrow">"明日"</string>
<string name="oneMonthDurationPast">"1か月前"</string>
<string name="beforeOneMonthDurationPast">"1か月前"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"週間"</string>
<string name="year">"年"</string>
<string name="years">"年"</string>
- <string name="sunday">"日曜日"</string>
- <string name="monday">"月曜日"</string>
- <string name="tuesday">"火曜日"</string>
- <string name="wednesday">"水曜日"</string>
- <string name="thursday">"木曜日"</string>
- <string name="friday">"金曜日"</string>
- <string name="saturday">"土曜日"</string>
<string name="every_weekday">"平日(月~金)"</string>
<string name="daily">"毎日"</string>
<string name="weekly">"毎週<xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"この動画はご使用の端末でストリーミングできません。"</string>
<string name="VideoView_error_text_unknown">"この動画は再生できません。"</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g><xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'日 '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>'年'<xliff:g id="MONTH">MMMM</xliff:g>'月'<xliff:g id="DAY">d</xliff:g>'日'"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>'年'"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'/'<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"正午"</string>
<string name="Noon">"正午"</string>
<string name="midnight">"午前0時"</string>
<string name="Midnight">"午前0時"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日"</string>
- <string name="month_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%B</xliff:g>/<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%b</xliff:g>/<xliff:g id="DAY">%-d</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%b</xliff:g>月"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g>/<xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"日曜日"</string>
- <string name="day_of_week_long_monday">"月曜日"</string>
- <string name="day_of_week_long_tuesday">"火曜日"</string>
- <string name="day_of_week_long_wednesday">"水曜日"</string>
- <string name="day_of_week_long_thursday">"木曜日"</string>
- <string name="day_of_week_long_friday">"金曜日"</string>
- <string name="day_of_week_long_saturday">"土曜日"</string>
- <string name="day_of_week_medium_sunday">"(日)"</string>
- <string name="day_of_week_medium_monday">"(月)"</string>
- <string name="day_of_week_medium_tuesday">"(火)"</string>
- <string name="day_of_week_medium_wednesday">"(水)"</string>
- <string name="day_of_week_medium_thursday">"(木)"</string>
- <string name="day_of_week_medium_friday">"(金)"</string>
- <string name="day_of_week_medium_saturday">"(土)"</string>
- <string name="day_of_week_short_sunday">"日"</string>
- <string name="day_of_week_short_monday">"月"</string>
- <string name="day_of_week_short_tuesday">"火"</string>
- <string name="day_of_week_short_wednesday">"水"</string>
- <string name="day_of_week_short_thursday">"木"</string>
- <string name="day_of_week_short_friday">"金"</string>
- <string name="day_of_week_short_saturday">"土"</string>
- <string name="day_of_week_shorter_sunday">"日"</string>
- <string name="day_of_week_shorter_monday">"月"</string>
- <string name="day_of_week_shorter_tuesday">"火"</string>
- <string name="day_of_week_shorter_wednesday">"水"</string>
- <string name="day_of_week_shorter_thursday">"木"</string>
- <string name="day_of_week_shorter_friday">"金"</string>
- <string name="day_of_week_shorter_saturday">"土"</string>
- <string name="day_of_week_shortest_sunday">"日"</string>
- <string name="day_of_week_shortest_monday">"月"</string>
- <string name="day_of_week_shortest_tuesday">"火"</string>
- <string name="day_of_week_shortest_wednesday">"水"</string>
- <string name="day_of_week_shortest_thursday">"火"</string>
- <string name="day_of_week_shortest_friday">"金"</string>
- <string name="day_of_week_shortest_saturday">"土"</string>
- <string name="month_long_january">"1月"</string>
- <string name="month_long_february">"2月"</string>
- <string name="month_long_march">"3月"</string>
- <string name="month_long_april">"4月"</string>
- <string name="month_long_may">"5月"</string>
- <string name="month_long_june">"6月"</string>
- <string name="month_long_july">"7月"</string>
- <string name="month_long_august">"8月"</string>
- <string name="month_long_september">"9月"</string>
- <string name="month_long_october">"10月"</string>
- <string name="month_long_november">"11月"</string>
- <string name="month_long_december">"12月"</string>
- <string name="month_medium_january">"1"</string>
- <string name="month_medium_february">"2"</string>
- <string name="month_medium_march">"3"</string>
- <string name="month_medium_april">"4"</string>
- <string name="month_medium_may">"5"</string>
- <string name="month_medium_june">"6"</string>
- <string name="month_medium_july">"7"</string>
- <string name="month_medium_august">"8"</string>
- <string name="month_medium_september">"9"</string>
- <string name="month_medium_october">"10"</string>
- <string name="month_medium_november">"11"</string>
- <string name="month_medium_december">"12"</string>
- <string name="month_shortest_january">"1"</string>
- <string name="month_shortest_february">"2"</string>
- <string name="month_shortest_march">"3"</string>
- <string name="month_shortest_april">"4"</string>
- <string name="month_shortest_may">"5"</string>
- <string name="month_shortest_june">"6"</string>
- <string name="month_shortest_july">"7"</string>
- <string name="month_shortest_august">"8"</string>
- <string name="month_shortest_september">"9"</string>
- <string name="month_shortest_october">"10"</string>
- <string name="month_shortest_november">"11"</string>
- <string name="month_shortest_december">"12"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"すべて選択"</string>
diff --git a/core/res/res/values-ko-rKR/donottranslate-cldr.xml b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
new file mode 100644
index 0000000..17d9432
--- /dev/null
+++ b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">1월</string>
+ <string name="month_long_standalone_february">2월</string>
+ <string name="month_long_standalone_march">3월</string>
+ <string name="month_long_standalone_april">4월</string>
+ <string name="month_long_standalone_may">5월</string>
+ <string name="month_long_standalone_june">6월</string>
+ <string name="month_long_standalone_july">7월</string>
+ <string name="month_long_standalone_august">8월</string>
+ <string name="month_long_standalone_september">9월</string>
+ <string name="month_long_standalone_october">10월</string>
+ <string name="month_long_standalone_november">11월</string>
+ <string name="month_long_standalone_december">12월</string>
+
+ <string name="month_long_january">1월</string>
+ <string name="month_long_february">2월</string>
+ <string name="month_long_march">3월</string>
+ <string name="month_long_april">4월</string>
+ <string name="month_long_may">5월</string>
+ <string name="month_long_june">6월</string>
+ <string name="month_long_july">7월</string>
+ <string name="month_long_august">8월</string>
+ <string name="month_long_september">9월</string>
+ <string name="month_long_october">10월</string>
+ <string name="month_long_november">11월</string>
+ <string name="month_long_december">12월</string>
+
+
+ <string name="month_shortest_january">1월</string>
+ <string name="month_shortest_february">2월</string>
+ <string name="month_shortest_march">3월</string>
+ <string name="month_shortest_april">4월</string>
+ <string name="month_shortest_may">5월</string>
+ <string name="month_shortest_june">6월</string>
+ <string name="month_shortest_july">7월</string>
+ <string name="month_shortest_august">8월</string>
+ <string name="month_shortest_september">9월</string>
+ <string name="month_shortest_october">10월</string>
+ <string name="month_shortest_november">11월</string>
+ <string name="month_shortest_december">12월</string>
+
+ <string name="day_of_week_long_sunday">일요일</string>
+ <string name="day_of_week_long_monday">월요일</string>
+ <string name="day_of_week_long_tuesday">화요일</string>
+ <string name="day_of_week_long_wednesday">수요일</string>
+ <string name="day_of_week_long_thursday">목요일</string>
+ <string name="day_of_week_long_friday">금요일</string>
+ <string name="day_of_week_long_saturday">토요일</string>
+
+ <string name="day_of_week_medium_sunday">일</string>
+ <string name="day_of_week_medium_monday">월</string>
+ <string name="day_of_week_medium_tuesday">화</string>
+ <string name="day_of_week_medium_wednesday">수</string>
+ <string name="day_of_week_medium_thursday">목</string>
+ <string name="day_of_week_medium_friday">금</string>
+ <string name="day_of_week_medium_saturday">토</string>
+
+ <string name="day_of_week_short_sunday">일</string>
+ <string name="day_of_week_short_monday">월</string>
+ <string name="day_of_week_short_tuesday">화</string>
+ <string name="day_of_week_short_wednesday">수</string>
+ <string name="day_of_week_short_thursday">목</string>
+ <string name="day_of_week_short_friday">금</string>
+ <string name="day_of_week_short_saturday">토</string>
+
+ <string name="day_of_week_shortest_sunday">일</string>
+ <string name="day_of_week_shortest_monday">월</string>
+ <string name="day_of_week_shortest_tuesday">화</string>
+ <string name="day_of_week_shortest_wednesday">수</string>
+ <string name="day_of_week_shortest_thursday">목</string>
+ <string name="day_of_week_shortest_friday">금</string>
+ <string name="day_of_week_shortest_saturday">토</string>
+
+ <string name="am">오전</string>
+ <string name="pm">오후</string>
+ <string name="yesterday">어제</string>
+ <string name="today">오늘</string>
+ <string name="tomorrow">내일</string>
+
+ <string name="hour_minute_ampm">%p %-l:%M</string>
+ <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="numeric_date">%Y. %-m. %-e.</string>
+ <string name="numeric_date_format">yyyy. M. d.</string>
+ <string name="month_day_year">%Y년 %-m월 %-e일</string>
+ <string name="time_of_day">%p %-l:%M:%S</string>
+ <string name="date_and_time">%p %-l:%M:%S %Y. %-m. %-e.</string>
+ <string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
+ <string name="month_day">%B %-e일</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y년 %B</string>
+ <string name="abbrev_month_day">%b %-e일</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y년 %b</string>
+</resources>
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
new file mode 100644
index 0000000..17d9432
--- /dev/null
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">1월</string>
+ <string name="month_long_standalone_february">2월</string>
+ <string name="month_long_standalone_march">3월</string>
+ <string name="month_long_standalone_april">4월</string>
+ <string name="month_long_standalone_may">5월</string>
+ <string name="month_long_standalone_june">6월</string>
+ <string name="month_long_standalone_july">7월</string>
+ <string name="month_long_standalone_august">8월</string>
+ <string name="month_long_standalone_september">9월</string>
+ <string name="month_long_standalone_october">10월</string>
+ <string name="month_long_standalone_november">11월</string>
+ <string name="month_long_standalone_december">12월</string>
+
+ <string name="month_long_january">1월</string>
+ <string name="month_long_february">2월</string>
+ <string name="month_long_march">3월</string>
+ <string name="month_long_april">4월</string>
+ <string name="month_long_may">5월</string>
+ <string name="month_long_june">6월</string>
+ <string name="month_long_july">7월</string>
+ <string name="month_long_august">8월</string>
+ <string name="month_long_september">9월</string>
+ <string name="month_long_october">10월</string>
+ <string name="month_long_november">11월</string>
+ <string name="month_long_december">12월</string>
+
+
+ <string name="month_shortest_january">1월</string>
+ <string name="month_shortest_february">2월</string>
+ <string name="month_shortest_march">3월</string>
+ <string name="month_shortest_april">4월</string>
+ <string name="month_shortest_may">5월</string>
+ <string name="month_shortest_june">6월</string>
+ <string name="month_shortest_july">7월</string>
+ <string name="month_shortest_august">8월</string>
+ <string name="month_shortest_september">9월</string>
+ <string name="month_shortest_october">10월</string>
+ <string name="month_shortest_november">11월</string>
+ <string name="month_shortest_december">12월</string>
+
+ <string name="day_of_week_long_sunday">일요일</string>
+ <string name="day_of_week_long_monday">월요일</string>
+ <string name="day_of_week_long_tuesday">화요일</string>
+ <string name="day_of_week_long_wednesday">수요일</string>
+ <string name="day_of_week_long_thursday">목요일</string>
+ <string name="day_of_week_long_friday">금요일</string>
+ <string name="day_of_week_long_saturday">토요일</string>
+
+ <string name="day_of_week_medium_sunday">일</string>
+ <string name="day_of_week_medium_monday">월</string>
+ <string name="day_of_week_medium_tuesday">화</string>
+ <string name="day_of_week_medium_wednesday">수</string>
+ <string name="day_of_week_medium_thursday">목</string>
+ <string name="day_of_week_medium_friday">금</string>
+ <string name="day_of_week_medium_saturday">토</string>
+
+ <string name="day_of_week_short_sunday">일</string>
+ <string name="day_of_week_short_monday">월</string>
+ <string name="day_of_week_short_tuesday">화</string>
+ <string name="day_of_week_short_wednesday">수</string>
+ <string name="day_of_week_short_thursday">목</string>
+ <string name="day_of_week_short_friday">금</string>
+ <string name="day_of_week_short_saturday">토</string>
+
+ <string name="day_of_week_shortest_sunday">일</string>
+ <string name="day_of_week_shortest_monday">월</string>
+ <string name="day_of_week_shortest_tuesday">화</string>
+ <string name="day_of_week_shortest_wednesday">수</string>
+ <string name="day_of_week_shortest_thursday">목</string>
+ <string name="day_of_week_shortest_friday">금</string>
+ <string name="day_of_week_shortest_saturday">토</string>
+
+ <string name="am">오전</string>
+ <string name="pm">오후</string>
+ <string name="yesterday">어제</string>
+ <string name="today">오늘</string>
+ <string name="tomorrow">내일</string>
+
+ <string name="hour_minute_ampm">%p %-l:%M</string>
+ <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="numeric_date">%Y. %-m. %-e.</string>
+ <string name="numeric_date_format">yyyy. M. d.</string>
+ <string name="month_day_year">%Y년 %-m월 %-e일</string>
+ <string name="time_of_day">%p %-l:%M:%S</string>
+ <string name="date_and_time">%p %-l:%M:%S %Y. %-m. %-e.</string>
+ <string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
+ <string name="month_day">%B %-e일</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y년 %B</string>
+ <string name="abbrev_month_day">%b %-e일</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y년 %b</string>
+</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 96b897a..06b85e8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"비밀번호"</string>
<string name="lockscreen_glogin_submit_button">"로그인"</string>
<string name="lockscreen_glogin_invalid_input">"사용자 이름 또는 비밀번호가 잘못되었습니다."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"알림 지우기"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"입력"</string>
<string name="menu_delete_shortcut_label">"삭제"</string>
<string name="search_go">"검색"</string>
- <string name="today">"오늘"</string>
- <string name="yesterday">"어제"</string>
- <string name="tomorrow">"내일"</string>
<string name="oneMonthDurationPast">"한 달 전"</string>
<string name="beforeOneMonthDurationPast">"한 달 전"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"주"</string>
<string name="year">"년"</string>
<string name="years">"년"</string>
- <string name="sunday">"일요일"</string>
- <string name="monday">"월요일"</string>
- <string name="tuesday">"화요일"</string>
- <string name="wednesday">"수요일"</string>
- <string name="thursday">"목요일"</string>
- <string name="friday">"금요일"</string>
- <string name="saturday">"토요일"</string>
<string name="every_weekday">"주중 매일(월-금)"</string>
<string name="daily">"매일"</string>
<string name="weekly">"매주 <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"죄송합니다. 이 기기로의 스트리밍에 적합하지 않은 동영상입니다."</string>
<string name="VideoView_error_text_unknown">"죄송합니다. 동영상을 재생할 수 없습니다."</string>
<string name="VideoView_error_button">"확인"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"정오"</string>
<string name="Noon">"정오"</string>
<string name="midnight">"자정"</string>
<string name="Midnight">"자정"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>, <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>, <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g> <xliff:g id="MONTH">%b</xliff:g>, <xliff:g id="DAY">%-d</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"일요일"</string>
- <string name="day_of_week_long_monday">"월요일"</string>
- <string name="day_of_week_long_tuesday">"화요일"</string>
- <string name="day_of_week_long_wednesday">"수요일"</string>
- <string name="day_of_week_long_thursday">"목요일"</string>
- <string name="day_of_week_long_friday">"금요일"</string>
- <string name="day_of_week_long_saturday">"토요일"</string>
- <string name="day_of_week_medium_sunday">"일요일"</string>
- <string name="day_of_week_medium_monday">"월"</string>
- <string name="day_of_week_medium_tuesday">"화"</string>
- <string name="day_of_week_medium_wednesday">"수"</string>
- <string name="day_of_week_medium_thursday">"목"</string>
- <string name="day_of_week_medium_friday">"금"</string>
- <string name="day_of_week_medium_saturday">"토"</string>
- <string name="day_of_week_short_sunday">"일"</string>
- <string name="day_of_week_short_monday">"월"</string>
- <string name="day_of_week_short_tuesday">"화"</string>
- <string name="day_of_week_short_wednesday">"수"</string>
- <string name="day_of_week_short_thursday">"목"</string>
- <string name="day_of_week_short_friday">"금"</string>
- <string name="day_of_week_short_saturday">"토"</string>
- <string name="day_of_week_shorter_sunday">"일"</string>
- <string name="day_of_week_shorter_monday">"월"</string>
- <string name="day_of_week_shorter_tuesday">"화"</string>
- <string name="day_of_week_shorter_wednesday">"수"</string>
- <string name="day_of_week_shorter_thursday">"목"</string>
- <string name="day_of_week_shorter_friday">"금"</string>
- <string name="day_of_week_shorter_saturday">"토"</string>
- <string name="day_of_week_shortest_sunday">"일"</string>
- <string name="day_of_week_shortest_monday">"3월"</string>
- <string name="day_of_week_shortest_tuesday">"목"</string>
- <string name="day_of_week_shortest_wednesday">"수"</string>
- <string name="day_of_week_shortest_thursday">"목"</string>
- <string name="day_of_week_shortest_friday">"금"</string>
- <string name="day_of_week_shortest_saturday">"토"</string>
- <string name="month_long_january">"1월"</string>
- <string name="month_long_february">"2월"</string>
- <string name="month_long_march">"3월"</string>
- <string name="month_long_april">"4월"</string>
- <string name="month_long_may">"5월"</string>
- <string name="month_long_june">"6월"</string>
- <string name="month_long_july">"7월"</string>
- <string name="month_long_august">"8월"</string>
- <string name="month_long_september">"9월"</string>
- <string name="month_long_october">"10월"</string>
- <string name="month_long_november">"11월"</string>
- <string name="month_long_december">"12월"</string>
- <string name="month_medium_january">"1월"</string>
- <string name="month_medium_february">"2월"</string>
- <string name="month_medium_march">"3월"</string>
- <string name="month_medium_april">"4월"</string>
- <string name="month_medium_may">"5월"</string>
- <string name="month_medium_june">"6월"</string>
- <string name="month_medium_july">"7월"</string>
- <string name="month_medium_august">"8월"</string>
- <string name="month_medium_september">"9월"</string>
- <string name="month_medium_october">"10월"</string>
- <string name="month_medium_november">"11월"</string>
- <string name="month_medium_december">"12월"</string>
- <string name="month_shortest_january">"1월"</string>
- <string name="month_shortest_february">"금"</string>
- <string name="month_shortest_march">"3월"</string>
- <string name="month_shortest_april">"4월"</string>
- <string name="month_shortest_may">"5월"</string>
- <string name="month_shortest_june">"6월"</string>
- <string name="month_shortest_july">"7월"</string>
- <string name="month_shortest_august">"8월"</string>
- <string name="month_shortest_september">"9월"</string>
- <string name="month_shortest_october">"10월"</string>
- <string name="month_shortest_november">"11월"</string>
- <string name="month_shortest_december">"12월"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"모두 선택"</string>
diff --git a/core/res/res/values-lt-rLT/donottranslate-cldr.xml b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
new file mode 100644
index 0000000..629937b
--- /dev/null
+++ b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Sausis</string>
+ <string name="month_long_standalone_february">Vasaris</string>
+ <string name="month_long_standalone_march">Kovas</string>
+ <string name="month_long_standalone_april">Balandis</string>
+ <string name="month_long_standalone_may">Gegužė</string>
+ <string name="month_long_standalone_june">Birželis</string>
+ <string name="month_long_standalone_july">Liepa</string>
+ <string name="month_long_standalone_august">Rugpjūtis</string>
+ <string name="month_long_standalone_september">Rugsėjis</string>
+ <string name="month_long_standalone_october">Spalis</string>
+ <string name="month_long_standalone_november">Lapkritis</string>
+ <string name="month_long_standalone_december">Gruodis</string>
+
+ <string name="month_long_january">sausio</string>
+ <string name="month_long_february">vasario</string>
+ <string name="month_long_march">kovo</string>
+ <string name="month_long_april">balandžio</string>
+ <string name="month_long_may">gegužės</string>
+ <string name="month_long_june">birželio</string>
+ <string name="month_long_july">liepos</string>
+ <string name="month_long_august">rugpjūčio</string>
+ <string name="month_long_september">rugsėjo</string>
+ <string name="month_long_october">spalio</string>
+ <string name="month_long_november">lapkričio</string>
+ <string name="month_long_december">gruodžio</string>
+
+ <string name="month_medium_january">Sau</string>
+ <string name="month_medium_february">Vas</string>
+ <string name="month_medium_march">Kov</string>
+ <string name="month_medium_april">Bal</string>
+ <string name="month_medium_may">Geg</string>
+ <string name="month_medium_june">Bir</string>
+ <string name="month_medium_july">Lie</string>
+ <string name="month_medium_august">Rgp</string>
+ <string name="month_medium_september">Rgs</string>
+ <string name="month_medium_october">Spl</string>
+ <string name="month_medium_november">Lap</string>
+ <string name="month_medium_december">Grd</string>
+
+ <string name="month_shortest_january">S</string>
+ <string name="month_shortest_february">V</string>
+ <string name="month_shortest_march">K</string>
+ <string name="month_shortest_april">B</string>
+ <string name="month_shortest_may">G</string>
+ <string name="month_shortest_june">B</string>
+ <string name="month_shortest_july">L</string>
+ <string name="month_shortest_august">R</string>
+ <string name="month_shortest_september">R</string>
+ <string name="month_shortest_october">S</string>
+ <string name="month_shortest_november">L</string>
+ <string name="month_shortest_december">G</string>
+
+ <string name="day_of_week_long_sunday">sekmadienis</string>
+ <string name="day_of_week_long_monday">pirmadienis</string>
+ <string name="day_of_week_long_tuesday">antradienis</string>
+ <string name="day_of_week_long_wednesday">trečiadienis</string>
+ <string name="day_of_week_long_thursday">ketvirtadienis</string>
+ <string name="day_of_week_long_friday">penktadienis</string>
+ <string name="day_of_week_long_saturday">šeštadienis</string>
+
+ <string name="day_of_week_medium_sunday">Sk</string>
+ <string name="day_of_week_medium_monday">Pr</string>
+ <string name="day_of_week_medium_tuesday">An</string>
+ <string name="day_of_week_medium_wednesday">Tr</string>
+ <string name="day_of_week_medium_thursday">Kt</string>
+ <string name="day_of_week_medium_friday">Pn</string>
+ <string name="day_of_week_medium_saturday">Št</string>
+
+ <string name="day_of_week_short_sunday">Sk</string>
+ <string name="day_of_week_short_monday">Pr</string>
+ <string name="day_of_week_short_tuesday">An</string>
+ <string name="day_of_week_short_wednesday">Tr</string>
+ <string name="day_of_week_short_thursday">Kt</string>
+ <string name="day_of_week_short_friday">Pn</string>
+ <string name="day_of_week_short_saturday">Št</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">A</string>
+ <string name="day_of_week_shortest_wednesday">T</string>
+ <string name="day_of_week_shortest_thursday">K</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">Š</string>
+
+ <string name="am">priešpiet</string>
+ <string name="pm">popiet</string>
+ <string name="yesterday">vakar</string>
+ <string name="today">šiandien</string>
+ <string name="tomorrow">rytoj</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%Y-%m-%d</string>
+ <string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="month_day_year">%Y m. %B %-e d.</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %Y.%m.%d</string>
+ <string name="abbrev_month_day_year">%Y.%m.%d</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-lv-rLV/donottranslate-cldr.xml b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
new file mode 100644
index 0000000..d47a18f
--- /dev/null
+++ b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janvāris</string>
+ <string name="month_long_standalone_february">februāris</string>
+ <string name="month_long_standalone_march">marts</string>
+ <string name="month_long_standalone_april">aprīlis</string>
+ <string name="month_long_standalone_may">maijs</string>
+ <string name="month_long_standalone_june">jūnijs</string>
+ <string name="month_long_standalone_july">jūlijs</string>
+ <string name="month_long_standalone_august">augusts</string>
+ <string name="month_long_standalone_september">septembris</string>
+ <string name="month_long_standalone_october">oktobris</string>
+ <string name="month_long_standalone_november">novembris</string>
+ <string name="month_long_standalone_december">decembris</string>
+
+ <string name="month_long_january">janvāris</string>
+ <string name="month_long_february">februāris</string>
+ <string name="month_long_march">marts</string>
+ <string name="month_long_april">aprīlis</string>
+ <string name="month_long_may">maijs</string>
+ <string name="month_long_june">jūnijs</string>
+ <string name="month_long_july">jūlijs</string>
+ <string name="month_long_august">augusts</string>
+ <string name="month_long_september">septembris</string>
+ <string name="month_long_october">oktobris</string>
+ <string name="month_long_november">novembris</string>
+ <string name="month_long_december">decembris</string>
+
+ <string name="month_medium_january">janv.</string>
+ <string name="month_medium_february">febr.</string>
+ <string name="month_medium_march">marts</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">maijs</string>
+ <string name="month_medium_june">jūn.</string>
+ <string name="month_medium_july">jūl.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">svētdiena</string>
+ <string name="day_of_week_long_monday">pirmdiena</string>
+ <string name="day_of_week_long_tuesday">otrdiena</string>
+ <string name="day_of_week_long_wednesday">trešdiena</string>
+ <string name="day_of_week_long_thursday">ceturtdiena</string>
+ <string name="day_of_week_long_friday">piektdiena</string>
+ <string name="day_of_week_long_saturday">sestdiena</string>
+
+ <string name="day_of_week_medium_sunday">Sv</string>
+ <string name="day_of_week_medium_monday">Pr</string>
+ <string name="day_of_week_medium_tuesday">Ot</string>
+ <string name="day_of_week_medium_wednesday">Tr</string>
+ <string name="day_of_week_medium_thursday">Ce</string>
+ <string name="day_of_week_medium_friday">Pk</string>
+ <string name="day_of_week_medium_saturday">Se</string>
+
+ <string name="day_of_week_short_sunday">Sv</string>
+ <string name="day_of_week_short_monday">Pr</string>
+ <string name="day_of_week_short_tuesday">Ot</string>
+ <string name="day_of_week_short_wednesday">Tr</string>
+ <string name="day_of_week_short_thursday">Ce</string>
+ <string name="day_of_week_short_friday">Pk</string>
+ <string name="day_of_week_short_saturday">Se</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">O</string>
+ <string name="day_of_week_shortest_wednesday">T</string>
+ <string name="day_of_week_shortest_thursday">C</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">vakar</string>
+ <string name="today">šodien</string>
+ <string name="tomorrow">rīt</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%Y. gada %-e. %B</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %Y. gada %-e. %b</string>
+ <string name="abbrev_month_day_year">%Y. gada %-e. %b</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y. g. %B</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y. g. %b</string>
+</resources>
diff --git a/core/res/res/values-nb/donottranslate-cldr.xml b/core/res/res/values-nb/donottranslate-cldr.xml
new file mode 100644
index 0000000..f89e819
--- /dev/null
+++ b/core/res/res/values-nb/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januar</string>
+ <string name="month_long_standalone_february">februar</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">august</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">desember</string>
+
+ <string name="month_long_january">januar</string>
+ <string name="month_long_february">februar</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">august</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">desember</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mars</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">juni</string>
+ <string name="month_medium_july">juli</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sep.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">des.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">søndag</string>
+ <string name="day_of_week_long_monday">mandag</string>
+ <string name="day_of_week_long_tuesday">tirsdag</string>
+ <string name="day_of_week_long_wednesday">onsdag</string>
+ <string name="day_of_week_long_thursday">torsdag</string>
+ <string name="day_of_week_long_friday">fredag</string>
+ <string name="day_of_week_long_saturday">lørdag</string>
+
+ <string name="day_of_week_medium_sunday">søn.</string>
+ <string name="day_of_week_medium_monday">man.</string>
+ <string name="day_of_week_medium_tuesday">tir.</string>
+ <string name="day_of_week_medium_wednesday">ons.</string>
+ <string name="day_of_week_medium_thursday">tor.</string>
+ <string name="day_of_week_medium_friday">fre.</string>
+ <string name="day_of_week_medium_saturday">lør.</string>
+
+ <string name="day_of_week_short_sunday">søn.</string>
+ <string name="day_of_week_short_monday">man.</string>
+ <string name="day_of_week_short_tuesday">tir.</string>
+ <string name="day_of_week_short_wednesday">ons.</string>
+ <string name="day_of_week_short_thursday">tor.</string>
+ <string name="day_of_week_short_friday">fre.</string>
+ <string name="day_of_week_short_saturday">lør.</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">O</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">L</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">i går</string>
+ <string name="today">i dag</string>
+ <string name="tomorrow">i morgen</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %-e. %b %Y</string>
+ <string name="abbrev_month_day_year">%-e. %b %Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 7bed159..a28b12c 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -424,9 +424,6 @@
<string name="lockscreen_glogin_password_hint">"Password"</string>
<string name="lockscreen_glogin_submit_button">"Sign in"</string>
<string name="lockscreen_glogin_invalid_input">"Invalid username or password."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Fjern varslinger"</string>
@@ -458,9 +455,6 @@
<string name="menu_enter_shortcut_label">"enter"</string>
<string name="menu_delete_shortcut_label">"slett"</string>
<string name="search_go">"Søk"</string>
- <string name="today">"I dag"</string>
- <string name="yesterday">"I går"</string>
- <string name="tomorrow">"I morgen"</string>
<string name="oneMonthDurationPast">"For en måned siden"</string>
<string name="beforeOneMonthDurationPast">"For over en måned siden"</string>
<plurals name="num_seconds_ago">
@@ -542,13 +536,6 @@
<string name="weeks">"uker"</string>
<string name="year">"år"</string>
<string name="years">"år"</string>
- <string name="sunday">"søndag"</string>
- <string name="monday">"mandag"</string>
- <string name="tuesday">"tirsdag"</string>
- <string name="wednesday">"onsdag"</string>
- <string name="thursday">"torsdag"</string>
- <string name="friday">"fredag"</string>
- <string name="saturday">"lørdag"</string>
<string name="every_weekday">"Hverdager (man–fre)"</string>
<string name="daily">"Hver dag"</string>
<string name="weekly">"Hver <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -558,9 +545,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Beklager, denne videoen er ikke gyldig for streaming til denne enheten."</string>
<string name="VideoView_error_text_unknown">"Beklager, kan ikke spille denne videoen."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="YEAR">%Y</xliff:g>-<xliff:g id="MONTH">%m</xliff:g>-<xliff:g id="DAY">%d</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -572,12 +556,6 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>'., '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"middag"</string>
<string name="Noon">"Middag"</string>
<string name="midnight">"midnatt"</string>
@@ -586,10 +564,6 @@
<skip />
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -614,83 +588,10 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for abbrev_month_day (3156047263406783231) -->
<skip />
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"søndag"</string>
- <string name="day_of_week_long_monday">"mandag"</string>
- <string name="day_of_week_long_tuesday">"tirsdag"</string>
- <string name="day_of_week_long_wednesday">"onsdag"</string>
- <string name="day_of_week_long_thursday">"torsdag"</string>
- <string name="day_of_week_long_friday">"fredag"</string>
- <string name="day_of_week_long_saturday">"lørdag"</string>
- <string name="day_of_week_medium_sunday">"søn"</string>
- <string name="day_of_week_medium_monday">"man"</string>
- <string name="day_of_week_medium_tuesday">"tir"</string>
- <string name="day_of_week_medium_wednesday">"ons"</string>
- <string name="day_of_week_medium_thursday">"tor"</string>
- <string name="day_of_week_medium_friday">"fre"</string>
- <string name="day_of_week_medium_saturday">"lør"</string>
- <string name="day_of_week_short_sunday">"sø"</string>
- <string name="day_of_week_short_monday">"ma"</string>
- <string name="day_of_week_short_tuesday">"ti"</string>
- <string name="day_of_week_short_wednesday">"on"</string>
- <string name="day_of_week_short_thursday">"to"</string>
- <string name="day_of_week_short_friday">"fr"</string>
- <string name="day_of_week_short_saturday">"lø"</string>
- <string name="day_of_week_shorter_sunday">"S"</string>
- <string name="day_of_week_shorter_monday">"M"</string>
- <string name="day_of_week_shorter_tuesday">"Ti"</string>
- <string name="day_of_week_shorter_wednesday">"O"</string>
- <string name="day_of_week_shorter_thursday">"To"</string>
- <string name="day_of_week_shorter_friday">"F"</string>
- <string name="day_of_week_shorter_saturday">"L"</string>
- <string name="day_of_week_shortest_sunday">"S"</string>
- <string name="day_of_week_shortest_monday">"M"</string>
- <string name="day_of_week_shortest_tuesday">"T"</string>
- <string name="day_of_week_shortest_wednesday">"O"</string>
- <string name="day_of_week_shortest_thursday">"T"</string>
- <string name="day_of_week_shortest_friday">"F"</string>
- <string name="day_of_week_shortest_saturday">"L"</string>
- <string name="month_long_january">"januar"</string>
- <string name="month_long_february">"februar"</string>
- <string name="month_long_march">"mars"</string>
- <string name="month_long_april">"april"</string>
- <string name="month_long_may">"mai"</string>
- <string name="month_long_june">"juni"</string>
- <string name="month_long_july">"juli"</string>
- <string name="month_long_august">"august"</string>
- <string name="month_long_september">"september"</string>
- <string name="month_long_october">"oktober"</string>
- <string name="month_long_november">"november"</string>
- <string name="month_long_december">"desember"</string>
- <string name="month_medium_january">"jan"</string>
- <string name="month_medium_february">"feb"</string>
- <string name="month_medium_march">"mar"</string>
- <string name="month_medium_april">"apr"</string>
- <string name="month_medium_may">"mai"</string>
- <string name="month_medium_june">"jun"</string>
- <string name="month_medium_july">"jul"</string>
- <string name="month_medium_august">"aug"</string>
- <string name="month_medium_september">"sep"</string>
- <string name="month_medium_october">"okt"</string>
- <string name="month_medium_november">"nov"</string>
- <string name="month_medium_december">"des"</string>
- <string name="month_shortest_january">"J"</string>
- <string name="month_shortest_february">"F"</string>
- <string name="month_shortest_march">"M"</string>
- <string name="month_shortest_april">"A"</string>
- <string name="month_shortest_may">"M"</string>
- <string name="month_shortest_june">"J"</string>
- <string name="month_shortest_july">"J"</string>
- <string name="month_shortest_august">"A"</string>
- <string name="month_shortest_september">"S"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"D"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Merk alt"</string>
diff --git a/core/res/res/values-nl-rBE/donottranslate-cldr.xml b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
new file mode 100644
index 0000000..c3050c6
--- /dev/null
+++ b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januari</string>
+ <string name="month_long_standalone_february">februari</string>
+ <string name="month_long_standalone_march">maart</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">mei</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">augustus</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januari</string>
+ <string name="month_long_february">februari</string>
+ <string name="month_long_march">maart</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">mei</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">augustus</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mrt.</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">mei</string>
+ <string name="month_medium_june">jun.</string>
+ <string name="month_medium_july">jul.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sep.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">zondag</string>
+ <string name="day_of_week_long_monday">maandag</string>
+ <string name="day_of_week_long_tuesday">dinsdag</string>
+ <string name="day_of_week_long_wednesday">woensdag</string>
+ <string name="day_of_week_long_thursday">donderdag</string>
+ <string name="day_of_week_long_friday">vrijdag</string>
+ <string name="day_of_week_long_saturday">zaterdag</string>
+
+ <string name="day_of_week_medium_sunday">zo</string>
+ <string name="day_of_week_medium_monday">ma</string>
+ <string name="day_of_week_medium_tuesday">di</string>
+ <string name="day_of_week_medium_wednesday">wo</string>
+ <string name="day_of_week_medium_thursday">do</string>
+ <string name="day_of_week_medium_friday">vr</string>
+ <string name="day_of_week_medium_saturday">za</string>
+
+ <string name="day_of_week_short_sunday">zo</string>
+ <string name="day_of_week_short_monday">ma</string>
+ <string name="day_of_week_short_tuesday">di</string>
+ <string name="day_of_week_short_wednesday">wo</string>
+ <string name="day_of_week_short_thursday">do</string>
+ <string name="day_of_week_short_friday">vr</string>
+ <string name="day_of_week_short_saturday">za</string>
+
+ <string name="day_of_week_shortest_sunday">Z</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">Z</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Gisteren</string>
+ <string name="today">Vandaag</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%-e/%m/%Y</string>
+ <string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e-%b-%Y</string>
+ <string name="abbrev_month_day_year">%-e-%b-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e-%b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-nl-rNL/donottranslate-cldr.xml b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
new file mode 100644
index 0000000..b9e0407
--- /dev/null
+++ b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januari</string>
+ <string name="month_long_standalone_february">februari</string>
+ <string name="month_long_standalone_march">maart</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">mei</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">augustus</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januari</string>
+ <string name="month_long_february">februari</string>
+ <string name="month_long_march">maart</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">mei</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">augustus</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mrt.</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">mei</string>
+ <string name="month_medium_june">jun.</string>
+ <string name="month_medium_july">jul.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sep.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">zondag</string>
+ <string name="day_of_week_long_monday">maandag</string>
+ <string name="day_of_week_long_tuesday">dinsdag</string>
+ <string name="day_of_week_long_wednesday">woensdag</string>
+ <string name="day_of_week_long_thursday">donderdag</string>
+ <string name="day_of_week_long_friday">vrijdag</string>
+ <string name="day_of_week_long_saturday">zaterdag</string>
+
+ <string name="day_of_week_medium_sunday">zo</string>
+ <string name="day_of_week_medium_monday">ma</string>
+ <string name="day_of_week_medium_tuesday">di</string>
+ <string name="day_of_week_medium_wednesday">wo</string>
+ <string name="day_of_week_medium_thursday">do</string>
+ <string name="day_of_week_medium_friday">vr</string>
+ <string name="day_of_week_medium_saturday">za</string>
+
+ <string name="day_of_week_short_sunday">zo</string>
+ <string name="day_of_week_short_monday">ma</string>
+ <string name="day_of_week_short_tuesday">di</string>
+ <string name="day_of_week_short_wednesday">wo</string>
+ <string name="day_of_week_short_thursday">do</string>
+ <string name="day_of_week_short_friday">vr</string>
+ <string name="day_of_week_short_saturday">za</string>
+
+ <string name="day_of_week_shortest_sunday">Z</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">Z</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Gisteren</string>
+ <string name="today">Vandaag</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d-%m-%Y</string>
+ <string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e-%b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-nl/donottranslate-cldr.xml b/core/res/res/values-nl/donottranslate-cldr.xml
new file mode 100644
index 0000000..b9e0407
--- /dev/null
+++ b/core/res/res/values-nl/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januari</string>
+ <string name="month_long_standalone_february">februari</string>
+ <string name="month_long_standalone_march">maart</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">mei</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">augustus</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januari</string>
+ <string name="month_long_february">februari</string>
+ <string name="month_long_march">maart</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">mei</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">augustus</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mrt.</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">mei</string>
+ <string name="month_medium_june">jun.</string>
+ <string name="month_medium_july">jul.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sep.</string>
+ <string name="month_medium_october">okt.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">zondag</string>
+ <string name="day_of_week_long_monday">maandag</string>
+ <string name="day_of_week_long_tuesday">dinsdag</string>
+ <string name="day_of_week_long_wednesday">woensdag</string>
+ <string name="day_of_week_long_thursday">donderdag</string>
+ <string name="day_of_week_long_friday">vrijdag</string>
+ <string name="day_of_week_long_saturday">zaterdag</string>
+
+ <string name="day_of_week_medium_sunday">zo</string>
+ <string name="day_of_week_medium_monday">ma</string>
+ <string name="day_of_week_medium_tuesday">di</string>
+ <string name="day_of_week_medium_wednesday">wo</string>
+ <string name="day_of_week_medium_thursday">do</string>
+ <string name="day_of_week_medium_friday">vr</string>
+ <string name="day_of_week_medium_saturday">za</string>
+
+ <string name="day_of_week_short_sunday">zo</string>
+ <string name="day_of_week_short_monday">ma</string>
+ <string name="day_of_week_short_tuesday">di</string>
+ <string name="day_of_week_short_wednesday">wo</string>
+ <string name="day_of_week_short_thursday">do</string>
+ <string name="day_of_week_short_friday">vr</string>
+ <string name="day_of_week_short_saturday">za</string>
+
+ <string name="day_of_week_shortest_sunday">Z</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">D</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">D</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">Z</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Gisteren</string>
+ <string name="today">Vandaag</string>
+ <string name="tomorrow">Morgen</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d-%m-%Y</string>
+ <string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e-%b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3a9e32c..4437f29 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Wachtwoord"</string>
<string name="lockscreen_glogin_submit_button">"Aanmelden"</string>
<string name="lockscreen_glogin_invalid_input">"Gebruikersnaam of wachtwoord ongeldig."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Meldingen wissen"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"invoeren"</string>
<string name="menu_delete_shortcut_label">"verwijderen"</string>
<string name="search_go">"Zoeken"</string>
- <string name="today">"Vandaag"</string>
- <string name="yesterday">"Gisteren"</string>
- <string name="tomorrow">"Morgen"</string>
<string name="oneMonthDurationPast">"1 maand geleden"</string>
<string name="beforeOneMonthDurationPast">"Meer dan 1 maand geleden"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"weken"</string>
<string name="year">"jaar"</string>
<string name="years">"jaren"</string>
- <string name="sunday">"Zondag"</string>
- <string name="monday">"Maandag"</string>
- <string name="tuesday">"Dinsdag"</string>
- <string name="wednesday">"Woensdag"</string>
- <string name="thursday">"Donderdag"</string>
- <string name="friday">"Vrijdag"</string>
- <string name="saturday">"Zaterdag"</string>
<string name="every_weekday">"Elke weekdag (ma-vr)"</string>
<string name="daily">"Dagelijks"</string>
<string name="weekly">"Wekelijks op <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Deze video kan helaas niet worden gestreamd naar dit apparaat."</string>
<string name="VideoView_error_text_unknown">"Deze video kan niet worden afgespeeld."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"am"</string>
- <string name="pm">"pm"</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>-<xliff:g id="MONTH">%m</xliff:g>-<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"twaalf uur \'s middags"</string>
<string name="Noon">"Twaalf uur \'s middags"</string>
<string name="midnight">"middernacht"</string>
<string name="Midnight">"Middernacht"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"Zondag"</string>
- <string name="day_of_week_long_monday">"Maandag"</string>
- <string name="day_of_week_long_tuesday">"Dinsdag"</string>
- <string name="day_of_week_long_wednesday">"Woensdag"</string>
- <string name="day_of_week_long_thursday">"Donderdag"</string>
- <string name="day_of_week_long_friday">"Vrijdag"</string>
- <string name="day_of_week_long_saturday">"Zaterdag"</string>
- <string name="day_of_week_medium_sunday">"Zo"</string>
- <string name="day_of_week_medium_monday">"Ma"</string>
- <string name="day_of_week_medium_tuesday">"Di"</string>
- <string name="day_of_week_medium_wednesday">"Wo"</string>
- <string name="day_of_week_medium_thursday">"Do"</string>
- <string name="day_of_week_medium_friday">"Vr"</string>
- <string name="day_of_week_medium_saturday">"Za"</string>
- <string name="day_of_week_short_sunday">"Zo"</string>
- <string name="day_of_week_short_monday">"Ma"</string>
- <string name="day_of_week_short_tuesday">"Di"</string>
- <string name="day_of_week_short_wednesday">"Wo"</string>
- <string name="day_of_week_short_thursday">"Do"</string>
- <string name="day_of_week_short_friday">"Vr"</string>
- <string name="day_of_week_short_saturday">"Za"</string>
- <string name="day_of_week_shorter_sunday">"Zo"</string>
- <string name="day_of_week_shorter_monday">"M"</string>
- <string name="day_of_week_shorter_tuesday">"Di"</string>
- <string name="day_of_week_shorter_wednesday">"W"</string>
- <string name="day_of_week_shorter_thursday">"Do"</string>
- <string name="day_of_week_shorter_friday">"V"</string>
- <string name="day_of_week_shorter_saturday">"Za"</string>
- <string name="day_of_week_shortest_sunday">"Z"</string>
- <string name="day_of_week_shortest_monday">"M"</string>
- <string name="day_of_week_shortest_tuesday">"D"</string>
- <string name="day_of_week_shortest_wednesday">"W"</string>
- <string name="day_of_week_shortest_thursday">"D"</string>
- <string name="day_of_week_shortest_friday">"V"</string>
- <string name="day_of_week_shortest_saturday">"Z"</string>
- <string name="month_long_january">"Januari"</string>
- <string name="month_long_february">"Februari"</string>
- <string name="month_long_march">"Maart"</string>
- <string name="month_long_april">"April"</string>
- <string name="month_long_may">"Mei"</string>
- <string name="month_long_june">"Juni"</string>
- <string name="month_long_july">"Juli"</string>
- <string name="month_long_august">"Augustus"</string>
- <string name="month_long_september">"September"</string>
- <string name="month_long_october">"Oktober"</string>
- <string name="month_long_november">"November"</string>
- <string name="month_long_december">"December"</string>
- <string name="month_medium_january">"Jan"</string>
- <string name="month_medium_february">"Feb"</string>
- <string name="month_medium_march">"Mrt"</string>
- <string name="month_medium_april">"Apr"</string>
- <string name="month_medium_may">"Mei"</string>
- <string name="month_medium_june">"Jun"</string>
- <string name="month_medium_july">"Jul"</string>
- <string name="month_medium_august">"Aug"</string>
- <string name="month_medium_september">"Sep"</string>
- <string name="month_medium_october">"Okt"</string>
- <string name="month_medium_november">"Nov"</string>
- <string name="month_medium_december">"Dec"</string>
- <string name="month_shortest_january">"J"</string>
- <string name="month_shortest_february">"V"</string>
- <string name="month_shortest_march">"M"</string>
- <string name="month_shortest_april">"A"</string>
- <string name="month_shortest_may">"M"</string>
- <string name="month_shortest_june">"J"</string>
- <string name="month_shortest_july">"J"</string>
- <string name="month_shortest_august">"A"</string>
- <string name="month_shortest_september">"S"</string>
- <string name="month_shortest_october">"O"</string>
- <string name="month_shortest_november">"N"</string>
- <string name="month_shortest_december">"D"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Alles selecteren"</string>
diff --git a/core/res/res/values-pl-rPL/donottranslate-cldr.xml b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
new file mode 100644
index 0000000..0ae8b48
--- /dev/null
+++ b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">styczeń</string>
+ <string name="month_long_standalone_february">luty</string>
+ <string name="month_long_standalone_march">marzec</string>
+ <string name="month_long_standalone_april">kwiecień</string>
+ <string name="month_long_standalone_may">maj</string>
+ <string name="month_long_standalone_june">czerwiec</string>
+ <string name="month_long_standalone_july">lipiec</string>
+ <string name="month_long_standalone_august">sierpień</string>
+ <string name="month_long_standalone_september">wrzesień</string>
+ <string name="month_long_standalone_october">październik</string>
+ <string name="month_long_standalone_november">listopad</string>
+ <string name="month_long_standalone_december">grudzień</string>
+
+ <string name="month_long_january">stycznia</string>
+ <string name="month_long_february">lutego</string>
+ <string name="month_long_march">marca</string>
+ <string name="month_long_april">kwietnia</string>
+ <string name="month_long_may">maja</string>
+ <string name="month_long_june">czerwca</string>
+ <string name="month_long_july">lipca</string>
+ <string name="month_long_august">sierpnia</string>
+ <string name="month_long_september">września</string>
+ <string name="month_long_october">października</string>
+ <string name="month_long_november">listopada</string>
+ <string name="month_long_december">grudnia</string>
+
+ <string name="month_medium_january">sty</string>
+ <string name="month_medium_february">lut</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">kwi</string>
+ <string name="month_medium_may">maj</string>
+ <string name="month_medium_june">cze</string>
+ <string name="month_medium_july">lip</string>
+ <string name="month_medium_august">sie</string>
+ <string name="month_medium_september">wrz</string>
+ <string name="month_medium_october">paź</string>
+ <string name="month_medium_november">lis</string>
+ <string name="month_medium_december">gru</string>
+
+ <string name="month_shortest_january">s</string>
+ <string name="month_shortest_february">l</string>
+ <string name="month_shortest_march">m</string>
+ <string name="month_shortest_april">k</string>
+ <string name="month_shortest_may">m</string>
+ <string name="month_shortest_june">c</string>
+ <string name="month_shortest_july">l</string>
+ <string name="month_shortest_august">s</string>
+ <string name="month_shortest_september">w</string>
+ <string name="month_shortest_october">p</string>
+ <string name="month_shortest_november">l</string>
+ <string name="month_shortest_december">g</string>
+
+ <string name="day_of_week_long_sunday">niedziela</string>
+ <string name="day_of_week_long_monday">poniedziałek</string>
+ <string name="day_of_week_long_tuesday">wtorek</string>
+ <string name="day_of_week_long_wednesday">środa</string>
+ <string name="day_of_week_long_thursday">czwartek</string>
+ <string name="day_of_week_long_friday">piątek</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">niedz.</string>
+ <string name="day_of_week_medium_monday">pon.</string>
+ <string name="day_of_week_medium_tuesday">wt.</string>
+ <string name="day_of_week_medium_wednesday">śr.</string>
+ <string name="day_of_week_medium_thursday">czw.</string>
+ <string name="day_of_week_medium_friday">pt.</string>
+ <string name="day_of_week_medium_saturday">sob.</string>
+
+ <string name="day_of_week_short_sunday">niedz.</string>
+ <string name="day_of_week_short_monday">pon.</string>
+ <string name="day_of_week_short_tuesday">wt.</string>
+ <string name="day_of_week_short_wednesday">śr.</string>
+ <string name="day_of_week_short_thursday">czw.</string>
+ <string name="day_of_week_short_friday">pt.</string>
+ <string name="day_of_week_short_saturday">sob.</string>
+
+ <string name="day_of_week_shortest_sunday">N</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">W</string>
+ <string name="day_of_week_shortest_wednesday">Ś</string>
+ <string name="day_of_week_shortest_thursday">C</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Wczoraj</string>
+ <string name="today">Dzisiaj</string>
+ <string name="tomorrow">Jutro</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d-%m-%Y</string>
+ <string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d-%m-%Y</string>
+ <string name="abbrev_month_day_year">%d-%m-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-pl/donottranslate-cldr.xml b/core/res/res/values-pl/donottranslate-cldr.xml
new file mode 100644
index 0000000..0ae8b48
--- /dev/null
+++ b/core/res/res/values-pl/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">styczeń</string>
+ <string name="month_long_standalone_february">luty</string>
+ <string name="month_long_standalone_march">marzec</string>
+ <string name="month_long_standalone_april">kwiecień</string>
+ <string name="month_long_standalone_may">maj</string>
+ <string name="month_long_standalone_june">czerwiec</string>
+ <string name="month_long_standalone_july">lipiec</string>
+ <string name="month_long_standalone_august">sierpień</string>
+ <string name="month_long_standalone_september">wrzesień</string>
+ <string name="month_long_standalone_october">październik</string>
+ <string name="month_long_standalone_november">listopad</string>
+ <string name="month_long_standalone_december">grudzień</string>
+
+ <string name="month_long_january">stycznia</string>
+ <string name="month_long_february">lutego</string>
+ <string name="month_long_march">marca</string>
+ <string name="month_long_april">kwietnia</string>
+ <string name="month_long_may">maja</string>
+ <string name="month_long_june">czerwca</string>
+ <string name="month_long_july">lipca</string>
+ <string name="month_long_august">sierpnia</string>
+ <string name="month_long_september">września</string>
+ <string name="month_long_october">października</string>
+ <string name="month_long_november">listopada</string>
+ <string name="month_long_december">grudnia</string>
+
+ <string name="month_medium_january">sty</string>
+ <string name="month_medium_february">lut</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">kwi</string>
+ <string name="month_medium_may">maj</string>
+ <string name="month_medium_june">cze</string>
+ <string name="month_medium_july">lip</string>
+ <string name="month_medium_august">sie</string>
+ <string name="month_medium_september">wrz</string>
+ <string name="month_medium_october">paź</string>
+ <string name="month_medium_november">lis</string>
+ <string name="month_medium_december">gru</string>
+
+ <string name="month_shortest_january">s</string>
+ <string name="month_shortest_february">l</string>
+ <string name="month_shortest_march">m</string>
+ <string name="month_shortest_april">k</string>
+ <string name="month_shortest_may">m</string>
+ <string name="month_shortest_june">c</string>
+ <string name="month_shortest_july">l</string>
+ <string name="month_shortest_august">s</string>
+ <string name="month_shortest_september">w</string>
+ <string name="month_shortest_october">p</string>
+ <string name="month_shortest_november">l</string>
+ <string name="month_shortest_december">g</string>
+
+ <string name="day_of_week_long_sunday">niedziela</string>
+ <string name="day_of_week_long_monday">poniedziałek</string>
+ <string name="day_of_week_long_tuesday">wtorek</string>
+ <string name="day_of_week_long_wednesday">środa</string>
+ <string name="day_of_week_long_thursday">czwartek</string>
+ <string name="day_of_week_long_friday">piątek</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">niedz.</string>
+ <string name="day_of_week_medium_monday">pon.</string>
+ <string name="day_of_week_medium_tuesday">wt.</string>
+ <string name="day_of_week_medium_wednesday">śr.</string>
+ <string name="day_of_week_medium_thursday">czw.</string>
+ <string name="day_of_week_medium_friday">pt.</string>
+ <string name="day_of_week_medium_saturday">sob.</string>
+
+ <string name="day_of_week_short_sunday">niedz.</string>
+ <string name="day_of_week_short_monday">pon.</string>
+ <string name="day_of_week_short_tuesday">wt.</string>
+ <string name="day_of_week_short_wednesday">śr.</string>
+ <string name="day_of_week_short_thursday">czw.</string>
+ <string name="day_of_week_short_friday">pt.</string>
+ <string name="day_of_week_short_saturday">sob.</string>
+
+ <string name="day_of_week_shortest_sunday">N</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">W</string>
+ <string name="day_of_week_shortest_wednesday">Ś</string>
+ <string name="day_of_week_shortest_thursday">C</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Wczoraj</string>
+ <string name="today">Dzisiaj</string>
+ <string name="tomorrow">Jutro</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d-%m-%Y</string>
+ <string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d-%m-%Y</string>
+ <string name="abbrev_month_day_year">%d-%m-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 50d245b..2cd4841 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Hasło"</string>
<string name="lockscreen_glogin_submit_button">"Zaloguj"</string>
<string name="lockscreen_glogin_invalid_input">"Błędna nazwa użytkownika lub hasło."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Wyczyść powiadomienia"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"enter"</string>
<string name="menu_delete_shortcut_label">"usuń"</string>
<string name="search_go">"Szukaj"</string>
- <string name="today">"Dzisiaj"</string>
- <string name="yesterday">"Wczoraj"</string>
- <string name="tomorrow">"Jutro"</string>
<string name="oneMonthDurationPast">"1 miesiąc temu"</string>
<string name="beforeOneMonthDurationPast">"Ponad 1 miesiąc temu"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"tygodni"</string>
<string name="year">"rok"</string>
<string name="years">"lat"</string>
- <string name="sunday">"niedziela"</string>
- <string name="monday">"poniedziałek"</string>
- <string name="tuesday">"wtorek"</string>
- <string name="wednesday">"środa"</string>
- <string name="thursday">"czwartek"</string>
- <string name="friday">"piątek"</string>
- <string name="saturday">"sobota"</string>
<string name="every_weekday">"W każdy dzień roboczy (pon–pt)"</string>
<string name="daily">"Codziennie"</string>
<string name="weekly">"Co tydzień w <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Przepraszamy, ten film wideo nie nadaje się do przesyłania strumieniowego do tego urządzenia."</string>
<string name="VideoView_error_text_unknown">"Niestety, nie można odtworzyć tego filmu wideo."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="am">"rano"</string>
- <string name="pm">"po południu"</string>
- <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"południe"</string>
<string name="Noon">"Południe"</string>
<string name="midnight">"północ"</string>
<string name="Midnight">"Północ"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"niedziela"</string>
- <string name="day_of_week_long_monday">"poniedziałek"</string>
- <string name="day_of_week_long_tuesday">"wtorek"</string>
- <string name="day_of_week_long_wednesday">"środa"</string>
- <string name="day_of_week_long_thursday">"czwartek"</string>
- <string name="day_of_week_long_friday">"piątek"</string>
- <string name="day_of_week_long_saturday">"sobota"</string>
- <string name="day_of_week_medium_sunday">"Nie"</string>
- <string name="day_of_week_medium_monday">"Pon"</string>
- <string name="day_of_week_medium_tuesday">"Wt"</string>
- <string name="day_of_week_medium_wednesday">"Śro"</string>
- <string name="day_of_week_medium_thursday">"Czw"</string>
- <string name="day_of_week_medium_friday">"Pią"</string>
- <string name="day_of_week_medium_saturday">"Sob"</string>
- <string name="day_of_week_short_sunday">"Nd"</string>
- <string name="day_of_week_short_monday">"Pn"</string>
- <string name="day_of_week_short_tuesday">"Wt"</string>
- <string name="day_of_week_short_wednesday">"Śr"</string>
- <string name="day_of_week_short_thursday">"Czw"</string>
- <string name="day_of_week_short_friday">"Pt"</string>
- <string name="day_of_week_short_saturday">"So"</string>
- <string name="day_of_week_shorter_sunday">"Nd"</string>
- <string name="day_of_week_shorter_monday">"Pon"</string>
- <string name="day_of_week_shorter_tuesday">"Wt"</string>
- <string name="day_of_week_shorter_wednesday">"Śr"</string>
- <string name="day_of_week_shorter_thursday">"Czw"</string>
- <string name="day_of_week_shorter_friday">"Pt"</string>
- <string name="day_of_week_shorter_saturday">"So"</string>
- <string name="day_of_week_shortest_sunday">"Nd"</string>
- <string name="day_of_week_shortest_monday">"Pon"</string>
- <string name="day_of_week_shortest_tuesday">"Czw"</string>
- <string name="day_of_week_shortest_wednesday">"Śr"</string>
- <string name="day_of_week_shortest_thursday">"Czw"</string>
- <string name="day_of_week_shortest_friday">"Pt"</string>
- <string name="day_of_week_shortest_saturday">"Sob"</string>
- <string name="month_long_january">"Styczeń"</string>
- <string name="month_long_february">"Luty"</string>
- <string name="month_long_march">"Marzec"</string>
- <string name="month_long_april">"Kwiecień"</string>
- <string name="month_long_may">"Maj"</string>
- <string name="month_long_june">"Czerwiec"</string>
- <string name="month_long_july">"Lipiec"</string>
- <string name="month_long_august">"Sierpień"</string>
- <string name="month_long_september">"Wrzesień"</string>
- <string name="month_long_october">"Październik"</string>
- <string name="month_long_november">"Listopad"</string>
- <string name="month_long_december">"Grudzień"</string>
- <string name="month_medium_january">"Sty"</string>
- <string name="month_medium_february">"Lut"</string>
- <string name="month_medium_march">"Mar"</string>
- <string name="month_medium_april">"Kwi"</string>
- <string name="month_medium_may">"Maj"</string>
- <string name="month_medium_june">"Cze"</string>
- <string name="month_medium_july">"Lip"</string>
- <string name="month_medium_august">"Sie"</string>
- <string name="month_medium_september">"Wrz"</string>
- <string name="month_medium_october">"Paź"</string>
- <string name="month_medium_november">"Lis"</string>
- <string name="month_medium_december">"Gru"</string>
- <string name="month_shortest_january">"Sty"</string>
- <string name="month_shortest_february">"Lut"</string>
- <string name="month_shortest_march">"Pon"</string>
- <string name="month_shortest_april">"Kwi"</string>
- <string name="month_shortest_may">"Maj"</string>
- <string name="month_shortest_june">"Cze"</string>
- <string name="month_shortest_july">"Lip"</string>
- <string name="month_shortest_august">"Sie"</string>
- <string name="month_shortest_september">"Wrz"</string>
- <string name="month_shortest_october">"Paź"</string>
- <string name="month_shortest_november">"Lis"</string>
- <string name="month_shortest_december">"Gru"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Zaznacz wszystko"</string>
diff --git a/core/res/res/values-pt-rBR/donottranslate-cldr.xml b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
new file mode 100644
index 0000000..cf0c29e
--- /dev/null
+++ b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janeiro</string>
+ <string name="month_long_standalone_february">fevereiro</string>
+ <string name="month_long_standalone_march">março</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">maio</string>
+ <string name="month_long_standalone_june">junho</string>
+ <string name="month_long_standalone_july">julho</string>
+ <string name="month_long_standalone_august">agosto</string>
+ <string name="month_long_standalone_september">setembro</string>
+ <string name="month_long_standalone_october">outubro</string>
+ <string name="month_long_standalone_november">novembro</string>
+ <string name="month_long_standalone_december">dezembro</string>
+
+ <string name="month_long_january">janeiro</string>
+ <string name="month_long_february">fevereiro</string>
+ <string name="month_long_march">março</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">maio</string>
+ <string name="month_long_june">junho</string>
+ <string name="month_long_july">julho</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">setembro</string>
+ <string name="month_long_october">outubro</string>
+ <string name="month_long_november">novembro</string>
+ <string name="month_long_december">dezembro</string>
+
+ <string name="month_medium_january">jan</string>
+ <string name="month_medium_february">fev</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">abr</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">set</string>
+ <string name="month_medium_october">out</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">segunda-feira</string>
+ <string name="day_of_week_long_tuesday">terça-feira</string>
+ <string name="day_of_week_long_wednesday">quarta-feira</string>
+ <string name="day_of_week_long_thursday">quinta-feira</string>
+ <string name="day_of_week_long_friday">sexta-feira</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">seg</string>
+ <string name="day_of_week_medium_tuesday">ter</string>
+ <string name="day_of_week_medium_wednesday">qua</string>
+ <string name="day_of_week_medium_thursday">qui</string>
+ <string name="day_of_week_medium_friday">sex</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">seg</string>
+ <string name="day_of_week_short_tuesday">ter</string>
+ <string name="day_of_week_short_wednesday">qua</string>
+ <string name="day_of_week_short_thursday">qui</string>
+ <string name="day_of_week_short_friday">sex</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">S</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">Q</string>
+ <string name="day_of_week_shortest_thursday">Q</string>
+ <string name="day_of_week_shortest_friday">S</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Ontem</string>
+ <string name="today">Hoje</string>
+ <string name="tomorrow">Amanhã</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e de %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b de %Y</string>
+</resources>
diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
new file mode 100644
index 0000000..d42dc8f
--- /dev/null
+++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Janeiro</string>
+ <string name="month_long_standalone_february">Fevereiro</string>
+ <string name="month_long_standalone_march">Março</string>
+ <string name="month_long_standalone_april">Abril</string>
+ <string name="month_long_standalone_may">Maio</string>
+ <string name="month_long_standalone_june">Junho</string>
+ <string name="month_long_standalone_july">Julho</string>
+ <string name="month_long_standalone_august">Agosto</string>
+ <string name="month_long_standalone_september">Setembro</string>
+ <string name="month_long_standalone_october">Outubro</string>
+ <string name="month_long_standalone_november">Novembro</string>
+ <string name="month_long_standalone_december">Dezembro</string>
+
+ <string name="month_long_january">Janeiro</string>
+ <string name="month_long_february">Fevereiro</string>
+ <string name="month_long_march">Março</string>
+ <string name="month_long_april">Abril</string>
+ <string name="month_long_may">Maio</string>
+ <string name="month_long_june">Junho</string>
+ <string name="month_long_july">Julho</string>
+ <string name="month_long_august">Agosto</string>
+ <string name="month_long_september">Setembro</string>
+ <string name="month_long_october">Outubro</string>
+ <string name="month_long_november">Novembro</string>
+ <string name="month_long_december">Dezembro</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Fev</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Abr</string>
+ <string name="month_medium_may">Mai</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Ago</string>
+ <string name="month_medium_september">Set</string>
+ <string name="month_medium_october">Out</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">segunda-feira</string>
+ <string name="day_of_week_long_tuesday">terça-feira</string>
+ <string name="day_of_week_long_wednesday">quarta-feira</string>
+ <string name="day_of_week_long_thursday">quinta-feira</string>
+ <string name="day_of_week_long_friday">sexta-feira</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">seg</string>
+ <string name="day_of_week_medium_tuesday">ter</string>
+ <string name="day_of_week_medium_wednesday">qua</string>
+ <string name="day_of_week_medium_thursday">qui</string>
+ <string name="day_of_week_medium_friday">sex</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">seg</string>
+ <string name="day_of_week_short_tuesday">ter</string>
+ <string name="day_of_week_short_wednesday">qua</string>
+ <string name="day_of_week_short_thursday">qui</string>
+ <string name="day_of_week_short_friday">sex</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">S</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">Q</string>
+ <string name="day_of_week_shortest_thursday">Q</string>
+ <string name="day_of_week_shortest_friday">S</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">Antes do meio-dia</string>
+ <string name="pm">Depois do meio-dia</string>
+ <string name="yesterday">Ontem</string>
+ <string name="today">Hoje</string>
+ <string name="tomorrow">Amanhã</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e de %b de %Y</string>
+ <string name="abbrev_month_day_year">%-e de %b de %Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e de %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b de %Y</string>
+</resources>
diff --git a/core/res/res/values-ro-rRO/donottranslate-cldr.xml b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
new file mode 100644
index 0000000..1ed2c81
--- /dev/null
+++ b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">ianuarie</string>
+ <string name="month_long_standalone_february">februarie</string>
+ <string name="month_long_standalone_march">martie</string>
+ <string name="month_long_standalone_april">aprilie</string>
+ <string name="month_long_standalone_may">mai</string>
+ <string name="month_long_standalone_june">iunie</string>
+ <string name="month_long_standalone_july">iulie</string>
+ <string name="month_long_standalone_august">august</string>
+ <string name="month_long_standalone_september">septembrie</string>
+ <string name="month_long_standalone_october">octombrie</string>
+ <string name="month_long_standalone_november">noiembrie</string>
+ <string name="month_long_standalone_december">decembrie</string>
+
+ <string name="month_long_january">ianuarie</string>
+ <string name="month_long_february">februarie</string>
+ <string name="month_long_march">martie</string>
+ <string name="month_long_april">aprilie</string>
+ <string name="month_long_may">mai</string>
+ <string name="month_long_june">iunie</string>
+ <string name="month_long_july">iulie</string>
+ <string name="month_long_august">august</string>
+ <string name="month_long_september">septembrie</string>
+ <string name="month_long_october">octombrie</string>
+ <string name="month_long_november">noiembrie</string>
+ <string name="month_long_december">decembrie</string>
+
+ <string name="month_medium_january">ian.</string>
+ <string name="month_medium_february">feb.</string>
+ <string name="month_medium_march">mar.</string>
+ <string name="month_medium_april">apr.</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">iun.</string>
+ <string name="month_medium_july">iul.</string>
+ <string name="month_medium_august">aug.</string>
+ <string name="month_medium_september">sept.</string>
+ <string name="month_medium_october">oct.</string>
+ <string name="month_medium_november">nov.</string>
+ <string name="month_medium_december">dec.</string>
+
+ <string name="month_shortest_january">I</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">I</string>
+ <string name="month_shortest_july">I</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">duminică</string>
+ <string name="day_of_week_long_monday">luni</string>
+ <string name="day_of_week_long_tuesday">marți</string>
+ <string name="day_of_week_long_wednesday">miercuri</string>
+ <string name="day_of_week_long_thursday">joi</string>
+ <string name="day_of_week_long_friday">vineri</string>
+ <string name="day_of_week_long_saturday">sâmbătă</string>
+
+ <string name="day_of_week_medium_sunday">Du</string>
+ <string name="day_of_week_medium_monday">Lu</string>
+ <string name="day_of_week_medium_tuesday">Ma</string>
+ <string name="day_of_week_medium_wednesday">Mi</string>
+ <string name="day_of_week_medium_thursday">Jo</string>
+ <string name="day_of_week_medium_friday">Vi</string>
+ <string name="day_of_week_medium_saturday">Sâ</string>
+
+ <string name="day_of_week_short_sunday">Du</string>
+ <string name="day_of_week_short_monday">Lu</string>
+ <string name="day_of_week_short_tuesday">Ma</string>
+ <string name="day_of_week_short_wednesday">Mi</string>
+ <string name="day_of_week_short_thursday">Jo</string>
+ <string name="day_of_week_short_friday">Vi</string>
+ <string name="day_of_week_short_saturday">Sâ</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">L</string>
+ <string name="day_of_week_shortest_tuesday">M</string>
+ <string name="day_of_week_shortest_wednesday">M</string>
+ <string name="day_of_week_shortest_thursday">J</string>
+ <string name="day_of_week_shortest_friday">V</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">ieri</string>
+ <string name="today">azi</string>
+ <string name="tomorrow">mâine</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S, %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-ru-rRU/donottranslate-cldr.xml b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
new file mode 100644
index 0000000..8faeb44
--- /dev/null
+++ b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Январь</string>
+ <string name="month_long_standalone_february">Февраль</string>
+ <string name="month_long_standalone_march">Март</string>
+ <string name="month_long_standalone_april">Апрель</string>
+ <string name="month_long_standalone_may">Май</string>
+ <string name="month_long_standalone_june">Июнь</string>
+ <string name="month_long_standalone_july">Июль</string>
+ <string name="month_long_standalone_august">Август</string>
+ <string name="month_long_standalone_september">Сентябрь</string>
+ <string name="month_long_standalone_october">Октябрь</string>
+ <string name="month_long_standalone_november">Ноябрь</string>
+ <string name="month_long_standalone_december">Декабрь</string>
+
+ <string name="month_long_january">января</string>
+ <string name="month_long_february">февраля</string>
+ <string name="month_long_march">марта</string>
+ <string name="month_long_april">апреля</string>
+ <string name="month_long_may">мая</string>
+ <string name="month_long_june">июня</string>
+ <string name="month_long_july">июля</string>
+ <string name="month_long_august">августа</string>
+ <string name="month_long_september">сентября</string>
+ <string name="month_long_october">октября</string>
+ <string name="month_long_november">ноября</string>
+ <string name="month_long_december">декабря</string>
+
+ <string name="month_medium_january">янв.</string>
+ <string name="month_medium_february">февр.</string>
+ <string name="month_medium_march">марта</string>
+ <string name="month_medium_april">апр.</string>
+ <string name="month_medium_may">мая</string>
+ <string name="month_medium_june">июня</string>
+ <string name="month_medium_july">июля</string>
+ <string name="month_medium_august">авг.</string>
+ <string name="month_medium_september">сент.</string>
+ <string name="month_medium_october">окт.</string>
+ <string name="month_medium_november">нояб.</string>
+ <string name="month_medium_december">дек.</string>
+
+ <string name="month_shortest_january">Я</string>
+ <string name="month_shortest_february">Ф</string>
+ <string name="month_shortest_march">М</string>
+ <string name="month_shortest_april">А</string>
+ <string name="month_shortest_may">М</string>
+ <string name="month_shortest_june">И</string>
+ <string name="month_shortest_july">И</string>
+ <string name="month_shortest_august">А</string>
+ <string name="month_shortest_september">С</string>
+ <string name="month_shortest_october">О</string>
+ <string name="month_shortest_november">Н</string>
+ <string name="month_shortest_december">Д</string>
+
+ <string name="day_of_week_long_sunday">воскресенье</string>
+ <string name="day_of_week_long_monday">понедельник</string>
+ <string name="day_of_week_long_tuesday">вторник</string>
+ <string name="day_of_week_long_wednesday">среда</string>
+ <string name="day_of_week_long_thursday">четверг</string>
+ <string name="day_of_week_long_friday">пятница</string>
+ <string name="day_of_week_long_saturday">суббота</string>
+
+ <string name="day_of_week_medium_sunday">Вс</string>
+ <string name="day_of_week_medium_monday">Пн</string>
+ <string name="day_of_week_medium_tuesday">Вт</string>
+ <string name="day_of_week_medium_wednesday">Ср</string>
+ <string name="day_of_week_medium_thursday">Чт</string>
+ <string name="day_of_week_medium_friday">Пт</string>
+ <string name="day_of_week_medium_saturday">Сб</string>
+
+ <string name="day_of_week_short_sunday">Вс</string>
+ <string name="day_of_week_short_monday">Пн</string>
+ <string name="day_of_week_short_tuesday">Вт</string>
+ <string name="day_of_week_short_wednesday">Ср</string>
+ <string name="day_of_week_short_thursday">Чт</string>
+ <string name="day_of_week_short_friday">Пт</string>
+ <string name="day_of_week_short_saturday">Сб</string>
+
+ <string name="day_of_week_shortest_sunday">В</string>
+ <string name="day_of_week_shortest_monday">П</string>
+ <string name="day_of_week_shortest_tuesday">В</string>
+ <string name="day_of_week_shortest_wednesday">С</string>
+ <string name="day_of_week_shortest_thursday">Ч</string>
+ <string name="day_of_week_shortest_friday">П</string>
+ <string name="day_of_week_shortest_saturday">С</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Вчера</string>
+ <string name="today">Сегодня</string>
+ <string name="tomorrow">Завтра</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y г.</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml
new file mode 100644
index 0000000..8faeb44
--- /dev/null
+++ b/core/res/res/values-ru/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Январь</string>
+ <string name="month_long_standalone_february">Февраль</string>
+ <string name="month_long_standalone_march">Март</string>
+ <string name="month_long_standalone_april">Апрель</string>
+ <string name="month_long_standalone_may">Май</string>
+ <string name="month_long_standalone_june">Июнь</string>
+ <string name="month_long_standalone_july">Июль</string>
+ <string name="month_long_standalone_august">Август</string>
+ <string name="month_long_standalone_september">Сентябрь</string>
+ <string name="month_long_standalone_october">Октябрь</string>
+ <string name="month_long_standalone_november">Ноябрь</string>
+ <string name="month_long_standalone_december">Декабрь</string>
+
+ <string name="month_long_january">января</string>
+ <string name="month_long_february">февраля</string>
+ <string name="month_long_march">марта</string>
+ <string name="month_long_april">апреля</string>
+ <string name="month_long_may">мая</string>
+ <string name="month_long_june">июня</string>
+ <string name="month_long_july">июля</string>
+ <string name="month_long_august">августа</string>
+ <string name="month_long_september">сентября</string>
+ <string name="month_long_october">октября</string>
+ <string name="month_long_november">ноября</string>
+ <string name="month_long_december">декабря</string>
+
+ <string name="month_medium_january">янв.</string>
+ <string name="month_medium_february">февр.</string>
+ <string name="month_medium_march">марта</string>
+ <string name="month_medium_april">апр.</string>
+ <string name="month_medium_may">мая</string>
+ <string name="month_medium_june">июня</string>
+ <string name="month_medium_july">июля</string>
+ <string name="month_medium_august">авг.</string>
+ <string name="month_medium_september">сент.</string>
+ <string name="month_medium_october">окт.</string>
+ <string name="month_medium_november">нояб.</string>
+ <string name="month_medium_december">дек.</string>
+
+ <string name="month_shortest_january">Я</string>
+ <string name="month_shortest_february">Ф</string>
+ <string name="month_shortest_march">М</string>
+ <string name="month_shortest_april">А</string>
+ <string name="month_shortest_may">М</string>
+ <string name="month_shortest_june">И</string>
+ <string name="month_shortest_july">И</string>
+ <string name="month_shortest_august">А</string>
+ <string name="month_shortest_september">С</string>
+ <string name="month_shortest_october">О</string>
+ <string name="month_shortest_november">Н</string>
+ <string name="month_shortest_december">Д</string>
+
+ <string name="day_of_week_long_sunday">воскресенье</string>
+ <string name="day_of_week_long_monday">понедельник</string>
+ <string name="day_of_week_long_tuesday">вторник</string>
+ <string name="day_of_week_long_wednesday">среда</string>
+ <string name="day_of_week_long_thursday">четверг</string>
+ <string name="day_of_week_long_friday">пятница</string>
+ <string name="day_of_week_long_saturday">суббота</string>
+
+ <string name="day_of_week_medium_sunday">Вс</string>
+ <string name="day_of_week_medium_monday">Пн</string>
+ <string name="day_of_week_medium_tuesday">Вт</string>
+ <string name="day_of_week_medium_wednesday">Ср</string>
+ <string name="day_of_week_medium_thursday">Чт</string>
+ <string name="day_of_week_medium_friday">Пт</string>
+ <string name="day_of_week_medium_saturday">Сб</string>
+
+ <string name="day_of_week_short_sunday">Вс</string>
+ <string name="day_of_week_short_monday">Пн</string>
+ <string name="day_of_week_short_tuesday">Вт</string>
+ <string name="day_of_week_short_wednesday">Ср</string>
+ <string name="day_of_week_short_thursday">Чт</string>
+ <string name="day_of_week_short_friday">Пт</string>
+ <string name="day_of_week_short_saturday">Сб</string>
+
+ <string name="day_of_week_shortest_sunday">В</string>
+ <string name="day_of_week_shortest_monday">П</string>
+ <string name="day_of_week_shortest_tuesday">В</string>
+ <string name="day_of_week_shortest_wednesday">С</string>
+ <string name="day_of_week_shortest_thursday">Ч</string>
+ <string name="day_of_week_shortest_friday">П</string>
+ <string name="day_of_week_shortest_saturday">С</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Вчера</string>
+ <string name="today">Сегодня</string>
+ <string name="tomorrow">Завтра</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y г.</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fac6cb7..2a15c43 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"Пароль"</string>
<string name="lockscreen_glogin_submit_button">"Войти"</string>
<string name="lockscreen_glogin_invalid_input">"Недействительное имя пользователя или пароль."</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"Очистить уведомления"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"ввод"</string>
<string name="menu_delete_shortcut_label">"удалить"</string>
<string name="search_go">"Поиск"</string>
- <string name="today">"Сегодня"</string>
- <string name="yesterday">"Вчера"</string>
- <string name="tomorrow">"Завтра"</string>
<string name="oneMonthDurationPast">"1 месяц назад"</string>
<string name="beforeOneMonthDurationPast">"Больше 1 месяца назад"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"недели"</string>
<string name="year">"год"</string>
<string name="years">"годы"</string>
- <string name="sunday">"воскресенье"</string>
- <string name="monday">"понедельник"</string>
- <string name="tuesday">"вторник"</string>
- <string name="wednesday">"среда"</string>
- <string name="thursday">"четверг"</string>
- <string name="friday">"пятница"</string>
- <string name="saturday">"суббота"</string>
<string name="every_weekday">"По рабочим дням (пн-пт)"</string>
<string name="daily">"Ежедневно"</string>
<string name="weekly">"Еженедельно в: <xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"К сожалению, это видео не подходит для потокового воспроизведения на данном устройстве."</string>
<string name="VideoView_error_text_unknown">"К сожалению, это видео нельзя воспроизвести."</string>
<string name="VideoView_error_button">"ОК"</string>
- <string name="am">"AM"</string>
- <string name="pm">"PM"</string>
- <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"полдень"</string>
<string name="Noon">"Полдень"</string>
<string name="midnight">"полночь"</string>
<string name="Midnight">"Полночь"</string>
- <string name="month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g>"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="month_year">"<xliff:g id="YEAR">%Y</xliff:g> <xliff:g id="MONTH">%B</xliff:g> г."</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
- <string name="abbrev_month_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g> г."</string>
- <string name="abbrev_month_day">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"воскресенье"</string>
- <string name="day_of_week_long_monday">"понедельник"</string>
- <string name="day_of_week_long_tuesday">"вторник"</string>
- <string name="day_of_week_long_wednesday">"среда"</string>
- <string name="day_of_week_long_thursday">"четверг"</string>
- <string name="day_of_week_long_friday">"пятница"</string>
- <string name="day_of_week_long_saturday">"суббота"</string>
- <string name="day_of_week_medium_sunday">"вс"</string>
- <string name="day_of_week_medium_monday">"пн"</string>
- <string name="day_of_week_medium_tuesday">"вт"</string>
- <string name="day_of_week_medium_wednesday">"ср"</string>
- <string name="day_of_week_medium_thursday">"чт"</string>
- <string name="day_of_week_medium_friday">"пт"</string>
- <string name="day_of_week_medium_saturday">"сб"</string>
- <string name="day_of_week_short_sunday">"вс"</string>
- <string name="day_of_week_short_monday">"пн"</string>
- <string name="day_of_week_short_tuesday">"вт"</string>
- <string name="day_of_week_short_wednesday">"ср"</string>
- <string name="day_of_week_short_thursday">"чт"</string>
- <string name="day_of_week_short_friday">"пт"</string>
- <string name="day_of_week_short_saturday">"сб"</string>
- <string name="day_of_week_shorter_sunday">"вс"</string>
- <string name="day_of_week_shorter_monday">"пн"</string>
- <string name="day_of_week_shorter_tuesday">"вт"</string>
- <string name="day_of_week_shorter_wednesday">"с"</string>
- <string name="day_of_week_shorter_thursday">"чт"</string>
- <string name="day_of_week_shorter_friday">"пт"</string>
- <string name="day_of_week_shorter_saturday">"сб"</string>
- <string name="day_of_week_shortest_sunday">"в"</string>
- <string name="day_of_week_shortest_monday">"п"</string>
- <string name="day_of_week_shortest_tuesday">"в"</string>
- <string name="day_of_week_shortest_wednesday">"с"</string>
- <string name="day_of_week_shortest_thursday">"ч"</string>
- <string name="day_of_week_shortest_friday">"п"</string>
- <string name="day_of_week_shortest_saturday">"с"</string>
- <string name="month_long_january">"январь"</string>
- <string name="month_long_february">"февраль"</string>
- <string name="month_long_march">"март"</string>
- <string name="month_long_april">"апрель"</string>
- <string name="month_long_may">"май"</string>
- <string name="month_long_june">"июнь"</string>
- <string name="month_long_july">"июль"</string>
- <string name="month_long_august">"август"</string>
- <string name="month_long_september">"сентябрь"</string>
- <string name="month_long_october">"октябрь"</string>
- <string name="month_long_november">"ноябрь"</string>
- <string name="month_long_december">"декабрь"</string>
- <string name="month_medium_january">"янв"</string>
- <string name="month_medium_february">"фев"</string>
- <string name="month_medium_march">"мар"</string>
- <string name="month_medium_april">"апр"</string>
- <string name="month_medium_may">"май"</string>
- <string name="month_medium_june">"июн"</string>
- <string name="month_medium_july">"июл"</string>
- <string name="month_medium_august">"авг"</string>
- <string name="month_medium_september">"сен"</string>
- <string name="month_medium_october">"окт"</string>
- <string name="month_medium_november">"ноя"</string>
- <string name="month_medium_december">"дек"</string>
- <string name="month_shortest_january">"Я"</string>
- <string name="month_shortest_february">"ф"</string>
- <string name="month_shortest_march">"м"</string>
- <string name="month_shortest_april">"а"</string>
- <string name="month_shortest_may">"м"</string>
- <string name="month_shortest_june">"и"</string>
- <string name="month_shortest_july">"и"</string>
- <string name="month_shortest_august">"а"</string>
- <string name="month_shortest_september">"с"</string>
- <string name="month_shortest_october">"о"</string>
- <string name="month_shortest_november">"н"</string>
- <string name="month_shortest_december">"д"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"Выбрать все"</string>
diff --git a/core/res/res/values-sk-rSK/donottranslate-cldr.xml b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
new file mode 100644
index 0000000..05bc5d3
--- /dev/null
+++ b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">január</string>
+ <string name="month_long_standalone_february">február</string>
+ <string name="month_long_standalone_march">marec</string>
+ <string name="month_long_standalone_april">apríl</string>
+ <string name="month_long_standalone_may">máj</string>
+ <string name="month_long_standalone_june">jún</string>
+ <string name="month_long_standalone_july">júl</string>
+ <string name="month_long_standalone_august">august</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">október</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januára</string>
+ <string name="month_long_february">februára</string>
+ <string name="month_long_march">marca</string>
+ <string name="month_long_april">apríla</string>
+ <string name="month_long_may">mája</string>
+ <string name="month_long_june">júna</string>
+ <string name="month_long_july">júla</string>
+ <string name="month_long_august">augusta</string>
+ <string name="month_long_september">septembra</string>
+ <string name="month_long_october">októbra</string>
+ <string name="month_long_november">novembra</string>
+ <string name="month_long_december">decembra</string>
+
+ <string name="month_medium_january">jan</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">máj</string>
+ <string name="month_medium_june">jún</string>
+ <string name="month_medium_july">júl</string>
+ <string name="month_medium_august">aug</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">okt</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dec</string>
+
+ <string name="month_shortest_january">j</string>
+ <string name="month_shortest_february">f</string>
+ <string name="month_shortest_march">m</string>
+ <string name="month_shortest_april">a</string>
+ <string name="month_shortest_may">m</string>
+ <string name="month_shortest_june">j</string>
+ <string name="month_shortest_july">j</string>
+ <string name="month_shortest_august">a</string>
+ <string name="month_shortest_september">s</string>
+ <string name="month_shortest_october">o</string>
+ <string name="month_shortest_november">n</string>
+ <string name="month_shortest_december">d</string>
+
+ <string name="day_of_week_long_sunday">nedeľa</string>
+ <string name="day_of_week_long_monday">pondelok</string>
+ <string name="day_of_week_long_tuesday">utorok</string>
+ <string name="day_of_week_long_wednesday">streda</string>
+ <string name="day_of_week_long_thursday">štvrtok</string>
+ <string name="day_of_week_long_friday">piatok</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">ne</string>
+ <string name="day_of_week_medium_monday">po</string>
+ <string name="day_of_week_medium_tuesday">ut</string>
+ <string name="day_of_week_medium_wednesday">st</string>
+ <string name="day_of_week_medium_thursday">št</string>
+ <string name="day_of_week_medium_friday">pi</string>
+ <string name="day_of_week_medium_saturday">so</string>
+
+ <string name="day_of_week_short_sunday">ne</string>
+ <string name="day_of_week_short_monday">po</string>
+ <string name="day_of_week_short_tuesday">ut</string>
+ <string name="day_of_week_short_wednesday">st</string>
+ <string name="day_of_week_short_thursday">št</string>
+ <string name="day_of_week_short_friday">pi</string>
+ <string name="day_of_week_short_saturday">so</string>
+
+ <string name="day_of_week_shortest_sunday">N</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">U</string>
+ <string name="day_of_week_shortest_wednesday">S</string>
+ <string name="day_of_week_shortest_thursday">Š</string>
+ <string name="day_of_week_shortest_friday">P</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">dopoludnia</string>
+ <string name="pm">popoludní</string>
+ <string name="yesterday">Včera</string>
+ <string name="today">Dnes</string>
+ <string name="tomorrow">Zajtra</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%-e.%-m.%Y</string>
+ <string name="numeric_date_format">d.M.yyyy</string>
+ <string name="month_day_year">%-e. %B %Y</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e. %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-sl-rSI/donottranslate-cldr.xml b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
new file mode 100644
index 0000000..e24b070
--- /dev/null
+++ b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januar</string>
+ <string name="month_long_standalone_february">februar</string>
+ <string name="month_long_standalone_march">marec</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">maj</string>
+ <string name="month_long_standalone_june">junij</string>
+ <string name="month_long_standalone_july">julij</string>
+ <string name="month_long_standalone_august">avgust</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januar</string>
+ <string name="month_long_february">februar</string>
+ <string name="month_long_march">marec</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">maj</string>
+ <string name="month_long_june">junij</string>
+ <string name="month_long_july">julij</string>
+ <string name="month_long_august">avgust</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">maj</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">avg</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">okt</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dec</string>
+
+ <string name="month_shortest_january">j</string>
+ <string name="month_shortest_february">f</string>
+ <string name="month_shortest_march">m</string>
+ <string name="month_shortest_april">a</string>
+ <string name="month_shortest_may">m</string>
+ <string name="month_shortest_june">j</string>
+ <string name="month_shortest_july">j</string>
+ <string name="month_shortest_august">a</string>
+ <string name="month_shortest_september">s</string>
+ <string name="month_shortest_october">o</string>
+ <string name="month_shortest_november">n</string>
+ <string name="month_shortest_december">d</string>
+
+ <string name="day_of_week_long_sunday">nedelja</string>
+ <string name="day_of_week_long_monday">ponedeljek</string>
+ <string name="day_of_week_long_tuesday">torek</string>
+ <string name="day_of_week_long_wednesday">sreda</string>
+ <string name="day_of_week_long_thursday">četrtek</string>
+ <string name="day_of_week_long_friday">petek</string>
+ <string name="day_of_week_long_saturday">sobota</string>
+
+ <string name="day_of_week_medium_sunday">ned</string>
+ <string name="day_of_week_medium_monday">pon</string>
+ <string name="day_of_week_medium_tuesday">tor</string>
+ <string name="day_of_week_medium_wednesday">sre</string>
+ <string name="day_of_week_medium_thursday">čet</string>
+ <string name="day_of_week_medium_friday">pet</string>
+ <string name="day_of_week_medium_saturday">sob</string>
+
+ <string name="day_of_week_short_sunday">ned</string>
+ <string name="day_of_week_short_monday">pon</string>
+ <string name="day_of_week_short_tuesday">tor</string>
+ <string name="day_of_week_short_wednesday">sre</string>
+ <string name="day_of_week_short_thursday">čet</string>
+ <string name="day_of_week_short_friday">pet</string>
+ <string name="day_of_week_short_saturday">sob</string>
+
+ <string name="day_of_week_shortest_sunday">n</string>
+ <string name="day_of_week_shortest_monday">p</string>
+ <string name="day_of_week_shortest_tuesday">t</string>
+ <string name="day_of_week_shortest_wednesday">s</string>
+ <string name="day_of_week_shortest_thursday">č</string>
+ <string name="day_of_week_shortest_friday">p</string>
+ <string name="day_of_week_shortest_saturday">s</string>
+
+ <string name="am">dop.</string>
+ <string name="pm">pop.</string>
+ <string name="yesterday">Včeraj</string>
+ <string name="today">Danes</string>
+ <string name="tomorrow">Jutri</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%-e. %m. %Y</string>
+ <string name="numeric_date_format">d. MM. yyyy</string>
+ <string name="month_day_year">%d. %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e. %b. %Y</string>
+ <string name="abbrev_month_day_year">%-e. %b. %Y</string>
+ <string name="month_day">%-e. %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-sr-rRS/donottranslate-cldr.xml b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
new file mode 100644
index 0000000..7f98ae2
--- /dev/null
+++ b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">јануар</string>
+ <string name="month_long_standalone_february">фебруар</string>
+ <string name="month_long_standalone_march">март</string>
+ <string name="month_long_standalone_april">април</string>
+ <string name="month_long_standalone_may">мај</string>
+ <string name="month_long_standalone_june">јун</string>
+ <string name="month_long_standalone_july">јул</string>
+ <string name="month_long_standalone_august">август</string>
+ <string name="month_long_standalone_september">септембар</string>
+ <string name="month_long_standalone_october">октобар</string>
+ <string name="month_long_standalone_november">новембар</string>
+ <string name="month_long_standalone_december">децембар</string>
+
+ <string name="month_long_january">јануар</string>
+ <string name="month_long_february">фебруар</string>
+ <string name="month_long_march">март</string>
+ <string name="month_long_april">април</string>
+ <string name="month_long_may">мај</string>
+ <string name="month_long_june">јун</string>
+ <string name="month_long_july">јул</string>
+ <string name="month_long_august">август</string>
+ <string name="month_long_september">септембар</string>
+ <string name="month_long_october">октобар</string>
+ <string name="month_long_november">новембар</string>
+ <string name="month_long_december">децембар</string>
+
+ <string name="month_medium_january">јан</string>
+ <string name="month_medium_february">феб</string>
+ <string name="month_medium_march">мар</string>
+ <string name="month_medium_april">апр</string>
+ <string name="month_medium_may">мај</string>
+ <string name="month_medium_june">јун</string>
+ <string name="month_medium_july">јул</string>
+ <string name="month_medium_august">авг</string>
+ <string name="month_medium_september">сеп</string>
+ <string name="month_medium_october">окт</string>
+ <string name="month_medium_november">нов</string>
+ <string name="month_medium_december">дец</string>
+
+ <string name="month_shortest_january">ј</string>
+ <string name="month_shortest_february">ф</string>
+ <string name="month_shortest_march">м</string>
+ <string name="month_shortest_april">а</string>
+ <string name="month_shortest_may">м</string>
+ <string name="month_shortest_june">ј</string>
+ <string name="month_shortest_july">ј</string>
+ <string name="month_shortest_august">а</string>
+ <string name="month_shortest_september">с</string>
+ <string name="month_shortest_october">о</string>
+ <string name="month_shortest_november">н</string>
+ <string name="month_shortest_december">д</string>
+
+ <string name="day_of_week_long_sunday">недеља</string>
+ <string name="day_of_week_long_monday">понедељак</string>
+ <string name="day_of_week_long_tuesday">уторак</string>
+ <string name="day_of_week_long_wednesday">среда</string>
+ <string name="day_of_week_long_thursday">четвртак</string>
+ <string name="day_of_week_long_friday">петак</string>
+ <string name="day_of_week_long_saturday">субота</string>
+
+ <string name="day_of_week_medium_sunday">нед</string>
+ <string name="day_of_week_medium_monday">пон</string>
+ <string name="day_of_week_medium_tuesday">уто</string>
+ <string name="day_of_week_medium_wednesday">сре</string>
+ <string name="day_of_week_medium_thursday">чет</string>
+ <string name="day_of_week_medium_friday">пет</string>
+ <string name="day_of_week_medium_saturday">суб</string>
+
+ <string name="day_of_week_short_sunday">нед</string>
+ <string name="day_of_week_short_monday">пон</string>
+ <string name="day_of_week_short_tuesday">уто</string>
+ <string name="day_of_week_short_wednesday">сре</string>
+ <string name="day_of_week_short_thursday">чет</string>
+ <string name="day_of_week_short_friday">пет</string>
+ <string name="day_of_week_short_saturday">суб</string>
+
+ <string name="day_of_week_shortest_sunday">н</string>
+ <string name="day_of_week_shortest_monday">п</string>
+ <string name="day_of_week_shortest_tuesday">у</string>
+ <string name="day_of_week_shortest_wednesday">с</string>
+ <string name="day_of_week_shortest_thursday">ч</string>
+ <string name="day_of_week_shortest_friday">п</string>
+ <string name="day_of_week_shortest_saturday">с</string>
+
+ <string name="am">пре подне</string>
+ <string name="pm">поподне</string>
+ <string name="yesterday">јуче</string>
+ <string name="today">данас</string>
+ <string name="tomorrow">сутра</string>
+
+ <string name="hour_minute_ampm">%H.%M</string>
+ <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="numeric_date">%-e.%-m.%Y.</string>
+ <string name="numeric_date_format">d.M.yyyy.</string>
+ <string name="month_day_year">%d. %B %Y.</string>
+ <string name="time_of_day">%H.%M.%S</string>
+ <string name="date_and_time">%H.%M.%S %d.%m.%Y.</string>
+ <string name="abbrev_month_day_year">%d.%m.%Y.</string>
+ <string name="month_day">%B %-e.</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%b %-e.</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b. %Y</string>
+</resources>
diff --git a/core/res/res/values-sv-rSE/donottranslate-cldr.xml b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
new file mode 100644
index 0000000..4570245
--- /dev/null
+++ b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">januari</string>
+ <string name="month_long_standalone_february">februari</string>
+ <string name="month_long_standalone_march">mars</string>
+ <string name="month_long_standalone_april">april</string>
+ <string name="month_long_standalone_may">maj</string>
+ <string name="month_long_standalone_june">juni</string>
+ <string name="month_long_standalone_july">juli</string>
+ <string name="month_long_standalone_august">augusti</string>
+ <string name="month_long_standalone_september">september</string>
+ <string name="month_long_standalone_october">oktober</string>
+ <string name="month_long_standalone_november">november</string>
+ <string name="month_long_standalone_december">december</string>
+
+ <string name="month_long_january">januari</string>
+ <string name="month_long_february">februari</string>
+ <string name="month_long_march">mars</string>
+ <string name="month_long_april">april</string>
+ <string name="month_long_may">maj</string>
+ <string name="month_long_june">juni</string>
+ <string name="month_long_july">juli</string>
+ <string name="month_long_august">augusti</string>
+ <string name="month_long_september">september</string>
+ <string name="month_long_october">oktober</string>
+ <string name="month_long_november">november</string>
+ <string name="month_long_december">december</string>
+
+ <string name="month_medium_january">jan</string>
+ <string name="month_medium_february">feb</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">apr</string>
+ <string name="month_medium_may">maj</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">aug</string>
+ <string name="month_medium_september">sep</string>
+ <string name="month_medium_october">okt</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">söndag</string>
+ <string name="day_of_week_long_monday">måndag</string>
+ <string name="day_of_week_long_tuesday">tisdag</string>
+ <string name="day_of_week_long_wednesday">onsdag</string>
+ <string name="day_of_week_long_thursday">torsdag</string>
+ <string name="day_of_week_long_friday">fredag</string>
+ <string name="day_of_week_long_saturday">lördag</string>
+
+ <string name="day_of_week_medium_sunday">sön</string>
+ <string name="day_of_week_medium_monday">mån</string>
+ <string name="day_of_week_medium_tuesday">tis</string>
+ <string name="day_of_week_medium_wednesday">ons</string>
+ <string name="day_of_week_medium_thursday">tors</string>
+ <string name="day_of_week_medium_friday">fre</string>
+ <string name="day_of_week_medium_saturday">lör</string>
+
+ <string name="day_of_week_short_sunday">sön</string>
+ <string name="day_of_week_short_monday">mån</string>
+ <string name="day_of_week_short_tuesday">tis</string>
+ <string name="day_of_week_short_wednesday">ons</string>
+ <string name="day_of_week_short_thursday">tors</string>
+ <string name="day_of_week_short_friday">fre</string>
+ <string name="day_of_week_short_saturday">lör</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">O</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">L</string>
+
+ <string name="am">f.m.</string>
+ <string name="pm">e.m.</string>
+ <string name="yesterday">igår</string>
+ <string name="today">idag</string>
+ <string name="tomorrow">imorgon</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%Y-%m-%d</string>
+ <string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y %B</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y %b</string>
+</resources>
diff --git a/core/res/res/values-th-rTH/donottranslate-cldr.xml b/core/res/res/values-th-rTH/donottranslate-cldr.xml
new file mode 100644
index 0000000..cc680f6
--- /dev/null
+++ b/core/res/res/values-th-rTH/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">มกราคม</string>
+ <string name="month_long_standalone_february">กุมภาพันธ์</string>
+ <string name="month_long_standalone_march">มีนาคม</string>
+ <string name="month_long_standalone_april">เมษายน</string>
+ <string name="month_long_standalone_may">พฤษภาคม</string>
+ <string name="month_long_standalone_june">มิถุนายน</string>
+ <string name="month_long_standalone_july">กรกฎาคม</string>
+ <string name="month_long_standalone_august">สิงหาคม</string>
+ <string name="month_long_standalone_september">กันยายน</string>
+ <string name="month_long_standalone_october">ตุลาคม</string>
+ <string name="month_long_standalone_november">พฤศจิกายน</string>
+ <string name="month_long_standalone_december">ธันวาคม</string>
+
+ <string name="month_long_january">มกราคม</string>
+ <string name="month_long_february">กุมภาพันธ์</string>
+ <string name="month_long_march">มีนาคม</string>
+ <string name="month_long_april">เมษายน</string>
+ <string name="month_long_may">พฤษภาคม</string>
+ <string name="month_long_june">มิถุนายน</string>
+ <string name="month_long_july">กรกฎาคม</string>
+ <string name="month_long_august">สิงหาคม</string>
+ <string name="month_long_september">กันยายน</string>
+ <string name="month_long_october">ตุลาคม</string>
+ <string name="month_long_november">พฤศจิกายน</string>
+ <string name="month_long_december">ธันวาคม</string>
+
+ <string name="month_medium_january">ม.ค.</string>
+ <string name="month_medium_february">ก.พ.</string>
+ <string name="month_medium_march">มี.ค.</string>
+ <string name="month_medium_april">เม.ย.</string>
+ <string name="month_medium_may">พ.ค.</string>
+ <string name="month_medium_june">มิ.ย.</string>
+ <string name="month_medium_july">ก.ค.</string>
+ <string name="month_medium_august">ส.ค.</string>
+ <string name="month_medium_september">ก.ย.</string>
+ <string name="month_medium_october">ต.ค.</string>
+ <string name="month_medium_november">พ.ย.</string>
+ <string name="month_medium_december">ธ.ค.</string>
+
+ <string name="month_shortest_january">ม.ค.</string>
+ <string name="month_shortest_february">ก.พ.</string>
+ <string name="month_shortest_march">มี.ค.</string>
+ <string name="month_shortest_april">เม.ย.</string>
+ <string name="month_shortest_may">พ.ค.</string>
+ <string name="month_shortest_june">มิ.ย.</string>
+ <string name="month_shortest_july">ก.ค.</string>
+ <string name="month_shortest_august">ส.ค.</string>
+ <string name="month_shortest_september">ก.ย.</string>
+ <string name="month_shortest_october">ต.ค.</string>
+ <string name="month_shortest_november">พ.ย.</string>
+ <string name="month_shortest_december">ธ.ค.</string>
+
+ <string name="day_of_week_long_sunday">วันอาทิตย์</string>
+ <string name="day_of_week_long_monday">วันจันทร์</string>
+ <string name="day_of_week_long_tuesday">วันอังคาร</string>
+ <string name="day_of_week_long_wednesday">วันพุธ</string>
+ <string name="day_of_week_long_thursday">วันพฤหัสบดี</string>
+ <string name="day_of_week_long_friday">วันศุกร์</string>
+ <string name="day_of_week_long_saturday">วันเสาร์</string>
+
+ <string name="day_of_week_medium_sunday">อา.</string>
+ <string name="day_of_week_medium_monday">จ.</string>
+ <string name="day_of_week_medium_tuesday">อ.</string>
+ <string name="day_of_week_medium_wednesday">พ.</string>
+ <string name="day_of_week_medium_thursday">พฤ.</string>
+ <string name="day_of_week_medium_friday">ศ.</string>
+ <string name="day_of_week_medium_saturday">ส.</string>
+
+ <string name="day_of_week_short_sunday">อา.</string>
+ <string name="day_of_week_short_monday">จ.</string>
+ <string name="day_of_week_short_tuesday">อ.</string>
+ <string name="day_of_week_short_wednesday">พ.</string>
+ <string name="day_of_week_short_thursday">พฤ.</string>
+ <string name="day_of_week_short_friday">ศ.</string>
+ <string name="day_of_week_short_saturday">ส.</string>
+
+ <string name="day_of_week_shortest_sunday">อ</string>
+ <string name="day_of_week_shortest_monday">จ</string>
+ <string name="day_of_week_shortest_tuesday">อ</string>
+ <string name="day_of_week_shortest_wednesday">พ</string>
+ <string name="day_of_week_shortest_thursday">พ</string>
+ <string name="day_of_week_shortest_friday">ศ</string>
+ <string name="day_of_week_shortest_saturday">ส</string>
+
+ <string name="am">ก่อนเที่ยง</string>
+ <string name="pm">หลังเที่ยง</string>
+ <string name="yesterday">เมื่อวาน</string>
+ <string name="today">วันนี้</string>
+ <string name="tomorrow">พรุ่งนี้</string>
+
+ <string name="hour_minute_ampm">%-k:%M</string>
+ <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="numeric_date">%-e/%-m/%Y</string>
+ <string name="numeric_date_format">d/M/yyyy</string>
+ <string name="month_day_year">%-e %B %Y</string>
+ <string name="time_of_day">%-k:%M:%S</string>
+ <string name="date_and_time">%-k:%M:%S, %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-tr-rTR/donottranslate-cldr.xml b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
new file mode 100644
index 0000000..acc0121
--- /dev/null
+++ b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Ocak</string>
+ <string name="month_long_standalone_february">Şubat</string>
+ <string name="month_long_standalone_march">Mart</string>
+ <string name="month_long_standalone_april">Nisan</string>
+ <string name="month_long_standalone_may">Mayıs</string>
+ <string name="month_long_standalone_june">Haziran</string>
+ <string name="month_long_standalone_july">Temmuz</string>
+ <string name="month_long_standalone_august">Ağustos</string>
+ <string name="month_long_standalone_september">Eylül</string>
+ <string name="month_long_standalone_october">Ekim</string>
+ <string name="month_long_standalone_november">Kasım</string>
+ <string name="month_long_standalone_december">Aralık</string>
+
+ <string name="month_long_january">Ocak</string>
+ <string name="month_long_february">Şubat</string>
+ <string name="month_long_march">Mart</string>
+ <string name="month_long_april">Nisan</string>
+ <string name="month_long_may">Mayıs</string>
+ <string name="month_long_june">Haziran</string>
+ <string name="month_long_july">Temmuz</string>
+ <string name="month_long_august">Ağustos</string>
+ <string name="month_long_september">Eylül</string>
+ <string name="month_long_october">Ekim</string>
+ <string name="month_long_november">Kasım</string>
+ <string name="month_long_december">Aralık</string>
+
+ <string name="month_medium_january">Oca</string>
+ <string name="month_medium_february">Şub</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Nis</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Haz</string>
+ <string name="month_medium_july">Tem</string>
+ <string name="month_medium_august">Ağu</string>
+ <string name="month_medium_september">Eyl</string>
+ <string name="month_medium_october">Eki</string>
+ <string name="month_medium_november">Kas</string>
+ <string name="month_medium_december">Ara</string>
+
+ <string name="month_shortest_january">O</string>
+ <string name="month_shortest_february">Ş</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">N</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">H</string>
+ <string name="month_shortest_july">T</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">E</string>
+ <string name="month_shortest_october">E</string>
+ <string name="month_shortest_november">K</string>
+ <string name="month_shortest_december">A</string>
+
+ <string name="day_of_week_long_sunday">Pazar</string>
+ <string name="day_of_week_long_monday">Pazartesi</string>
+ <string name="day_of_week_long_tuesday">Salı</string>
+ <string name="day_of_week_long_wednesday">Çarşamba</string>
+ <string name="day_of_week_long_thursday">Perşembe</string>
+ <string name="day_of_week_long_friday">Cuma</string>
+ <string name="day_of_week_long_saturday">Cumartesi</string>
+
+ <string name="day_of_week_medium_sunday">Paz</string>
+ <string name="day_of_week_medium_monday">Pzt</string>
+ <string name="day_of_week_medium_tuesday">Sal</string>
+ <string name="day_of_week_medium_wednesday">Çar</string>
+ <string name="day_of_week_medium_thursday">Per</string>
+ <string name="day_of_week_medium_friday">Cum</string>
+ <string name="day_of_week_medium_saturday">Cmt</string>
+
+ <string name="day_of_week_short_sunday">Paz</string>
+ <string name="day_of_week_short_monday">Pzt</string>
+ <string name="day_of_week_short_tuesday">Sal</string>
+ <string name="day_of_week_short_wednesday">Çar</string>
+ <string name="day_of_week_short_thursday">Per</string>
+ <string name="day_of_week_short_friday">Cum</string>
+ <string name="day_of_week_short_saturday">Cmt</string>
+
+ <string name="day_of_week_shortest_sunday">P</string>
+ <string name="day_of_week_shortest_monday">P</string>
+ <string name="day_of_week_shortest_tuesday">S</string>
+ <string name="day_of_week_shortest_wednesday">Ç</string>
+ <string name="day_of_week_shortest_thursday">P</string>
+ <string name="day_of_week_shortest_friday">C</string>
+ <string name="day_of_week_shortest_saturday">C</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Dün</string>
+ <string name="today">Bugün</string>
+ <string name="tomorrow">Yarın</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d %m %Y</string>
+ <string name="numeric_date_format">dd MM yyyy</string>
+ <string name="month_day_year">%d %B %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d %b %Y</string>
+ <string name="abbrev_month_day_year">%d %b %Y</string>
+ <string name="month_day">%d %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%d %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-uk-rUA/donottranslate-cldr.xml b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
new file mode 100644
index 0000000..888df36
--- /dev/null
+++ b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">Січень</string>
+ <string name="month_long_standalone_february">Лютий</string>
+ <string name="month_long_standalone_march">Березень</string>
+ <string name="month_long_standalone_april">Квітень</string>
+ <string name="month_long_standalone_may">Травень</string>
+ <string name="month_long_standalone_june">Червень</string>
+ <string name="month_long_standalone_july">Липень</string>
+ <string name="month_long_standalone_august">Серпень</string>
+ <string name="month_long_standalone_september">Вересень</string>
+ <string name="month_long_standalone_october">Жовтень</string>
+ <string name="month_long_standalone_november">Листопад</string>
+ <string name="month_long_standalone_december">Грудень</string>
+
+ <string name="month_long_january">січня</string>
+ <string name="month_long_february">лютого</string>
+ <string name="month_long_march">березня</string>
+ <string name="month_long_april">квітня</string>
+ <string name="month_long_may">травня</string>
+ <string name="month_long_june">червня</string>
+ <string name="month_long_july">липня</string>
+ <string name="month_long_august">серпня</string>
+ <string name="month_long_september">вересня</string>
+ <string name="month_long_october">жовтня</string>
+ <string name="month_long_november">листопада</string>
+ <string name="month_long_december">грудня</string>
+
+ <string name="month_medium_january">січ.</string>
+ <string name="month_medium_february">лют.</string>
+ <string name="month_medium_march">бер.</string>
+ <string name="month_medium_april">квіт.</string>
+ <string name="month_medium_may">трав.</string>
+ <string name="month_medium_june">черв.</string>
+ <string name="month_medium_july">лип.</string>
+ <string name="month_medium_august">серп.</string>
+ <string name="month_medium_september">вер.</string>
+ <string name="month_medium_october">жовт.</string>
+ <string name="month_medium_november">лист.</string>
+ <string name="month_medium_december">груд.</string>
+
+ <string name="month_shortest_january">С</string>
+ <string name="month_shortest_february">Л</string>
+ <string name="month_shortest_march">Б</string>
+ <string name="month_shortest_april">К</string>
+ <string name="month_shortest_may">Т</string>
+ <string name="month_shortest_june">Ч</string>
+ <string name="month_shortest_july">Л</string>
+ <string name="month_shortest_august">С</string>
+ <string name="month_shortest_september">В</string>
+ <string name="month_shortest_october">Ж</string>
+ <string name="month_shortest_november">Л</string>
+ <string name="month_shortest_december">Г</string>
+
+ <string name="day_of_week_long_sunday">Неділя</string>
+ <string name="day_of_week_long_monday">Понеділок</string>
+ <string name="day_of_week_long_tuesday">Вівторок</string>
+ <string name="day_of_week_long_wednesday">Середа</string>
+ <string name="day_of_week_long_thursday">Четвер</string>
+ <string name="day_of_week_long_friday">Пʼятниця</string>
+ <string name="day_of_week_long_saturday">Субота</string>
+
+ <string name="day_of_week_medium_sunday">Нд</string>
+ <string name="day_of_week_medium_monday">Пн</string>
+ <string name="day_of_week_medium_tuesday">Вт</string>
+ <string name="day_of_week_medium_wednesday">Ср</string>
+ <string name="day_of_week_medium_thursday">Чт</string>
+ <string name="day_of_week_medium_friday">Пт</string>
+ <string name="day_of_week_medium_saturday">Сб</string>
+
+ <string name="day_of_week_short_sunday">Нд</string>
+ <string name="day_of_week_short_monday">Пн</string>
+ <string name="day_of_week_short_tuesday">Вт</string>
+ <string name="day_of_week_short_wednesday">Ср</string>
+ <string name="day_of_week_short_thursday">Чт</string>
+ <string name="day_of_week_short_friday">Пт</string>
+ <string name="day_of_week_short_saturday">Сб</string>
+
+ <string name="day_of_week_shortest_sunday">Н</string>
+ <string name="day_of_week_shortest_monday">П</string>
+ <string name="day_of_week_shortest_tuesday">В</string>
+ <string name="day_of_week_shortest_wednesday">С</string>
+ <string name="day_of_week_shortest_thursday">Ч</string>
+ <string name="day_of_week_shortest_friday">П</string>
+ <string name="day_of_week_shortest_saturday">С</string>
+
+ <string name="am">дп</string>
+ <string name="pm">пп</string>
+ <string name="yesterday">Вчора</string>
+ <string name="today">Сьогодні</string>
+ <string name="tomorrow">Завтра</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d.%m.%Y</string>
+ <string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="month_day_year">%-e %B %Y р.</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="abbrev_month_day_year">%-e %b %Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%-B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%-b %Y</string>
+</resources>
diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
new file mode 100644
index 0000000..2a28b32
--- /dev/null
+++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">tháng một</string>
+ <string name="month_long_standalone_february">tháng hai</string>
+ <string name="month_long_standalone_march">tháng ba</string>
+ <string name="month_long_standalone_april">tháng tư</string>
+ <string name="month_long_standalone_may">tháng năm</string>
+ <string name="month_long_standalone_june">tháng sáu</string>
+ <string name="month_long_standalone_july">tháng bảy</string>
+ <string name="month_long_standalone_august">tháng tám</string>
+ <string name="month_long_standalone_september">tháng chín</string>
+ <string name="month_long_standalone_october">tháng mười</string>
+ <string name="month_long_standalone_november">tháng mười một</string>
+ <string name="month_long_standalone_december">tháng mười hai</string>
+
+ <string name="month_long_january">tháng một</string>
+ <string name="month_long_february">tháng hai</string>
+ <string name="month_long_march">tháng ba</string>
+ <string name="month_long_april">tháng tư</string>
+ <string name="month_long_may">tháng năm</string>
+ <string name="month_long_june">tháng sáu</string>
+ <string name="month_long_july">tháng bảy</string>
+ <string name="month_long_august">tháng tám</string>
+ <string name="month_long_september">tháng chín</string>
+ <string name="month_long_october">tháng mười</string>
+ <string name="month_long_november">tháng mười một</string>
+ <string name="month_long_december">tháng mười hai</string>
+
+ <string name="month_medium_january">thg 1</string>
+ <string name="month_medium_february">thg 2</string>
+ <string name="month_medium_march">thg 3</string>
+ <string name="month_medium_april">thg 4</string>
+ <string name="month_medium_may">thg 5</string>
+ <string name="month_medium_june">thg 6</string>
+ <string name="month_medium_july">thg 7</string>
+ <string name="month_medium_august">thg 8</string>
+ <string name="month_medium_september">thg 9</string>
+ <string name="month_medium_october">thg 10</string>
+ <string name="month_medium_november">thg 11</string>
+ <string name="month_medium_december">thg 12</string>
+
+ <string name="month_shortest_january">1</string>
+ <string name="month_shortest_february">2</string>
+ <string name="month_shortest_march">3</string>
+ <string name="month_shortest_april">4</string>
+ <string name="month_shortest_may">5</string>
+ <string name="month_shortest_june">6</string>
+ <string name="month_shortest_july">7</string>
+ <string name="month_shortest_august">8</string>
+ <string name="month_shortest_september">9</string>
+ <string name="month_shortest_october">10</string>
+ <string name="month_shortest_november">11</string>
+ <string name="month_shortest_december">12</string>
+
+ <string name="day_of_week_long_sunday">Chủ nhật</string>
+ <string name="day_of_week_long_monday">Thứ hai</string>
+ <string name="day_of_week_long_tuesday">Thứ ba</string>
+ <string name="day_of_week_long_wednesday">Thứ tư</string>
+ <string name="day_of_week_long_thursday">Thứ năm</string>
+ <string name="day_of_week_long_friday">Thứ sáu</string>
+ <string name="day_of_week_long_saturday">Thứ bảy</string>
+
+ <string name="day_of_week_medium_sunday">CN</string>
+ <string name="day_of_week_medium_monday">Th 2</string>
+ <string name="day_of_week_medium_tuesday">Th 3</string>
+ <string name="day_of_week_medium_wednesday">Th 4</string>
+ <string name="day_of_week_medium_thursday">Th 5</string>
+ <string name="day_of_week_medium_friday">Th 6</string>
+ <string name="day_of_week_medium_saturday">Th 7</string>
+
+ <string name="day_of_week_short_sunday">CN</string>
+ <string name="day_of_week_short_monday">Th 2</string>
+ <string name="day_of_week_short_tuesday">Th 3</string>
+ <string name="day_of_week_short_wednesday">Th 4</string>
+ <string name="day_of_week_short_thursday">Th 5</string>
+ <string name="day_of_week_short_friday">Th 6</string>
+ <string name="day_of_week_short_saturday">Th 7</string>
+
+ <string name="day_of_week_shortest_sunday">1</string>
+ <string name="day_of_week_shortest_monday">2</string>
+ <string name="day_of_week_shortest_tuesday">3</string>
+ <string name="day_of_week_shortest_wednesday">4</string>
+ <string name="day_of_week_shortest_thursday">5</string>
+ <string name="day_of_week_shortest_friday">6</string>
+ <string name="day_of_week_shortest_saturday">7</string>
+
+ <string name="am">SA</string>
+ <string name="pm">CH</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%H:%M</string>
+ <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="month_day_year">Ngày %d tháng %-m năm %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%d-%m-%Y %H:%M:%S</string>
+ <string name="abbrev_month_day_year">%d-%m-%Y</string>
+ <string name="month_day">%-e %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%-e %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values-zh-rCN/donottranslate-cldr.xml b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
new file mode 100644
index 0000000..18e37a9
--- /dev/null
+++ b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">一月</string>
+ <string name="month_long_standalone_february">二月</string>
+ <string name="month_long_standalone_march">三月</string>
+ <string name="month_long_standalone_april">四月</string>
+ <string name="month_long_standalone_may">五月</string>
+ <string name="month_long_standalone_june">六月</string>
+ <string name="month_long_standalone_july">七月</string>
+ <string name="month_long_standalone_august">八月</string>
+ <string name="month_long_standalone_september">九月</string>
+ <string name="month_long_standalone_october">十月</string>
+ <string name="month_long_standalone_november">十一月</string>
+ <string name="month_long_standalone_december">十二月</string>
+
+ <string name="month_long_january">1月</string>
+ <string name="month_long_february">2月</string>
+ <string name="month_long_march">3月</string>
+ <string name="month_long_april">4月</string>
+ <string name="month_long_may">5月</string>
+ <string name="month_long_june">6月</string>
+ <string name="month_long_july">7月</string>
+ <string name="month_long_august">8月</string>
+ <string name="month_long_september">9月</string>
+ <string name="month_long_october">10月</string>
+ <string name="month_long_november">11月</string>
+ <string name="month_long_december">12月</string>
+
+ <string name="month_medium_january">1月</string>
+ <string name="month_medium_february">2月</string>
+ <string name="month_medium_march">3月</string>
+ <string name="month_medium_april">4月</string>
+ <string name="month_medium_may">5月</string>
+ <string name="month_medium_june">6月</string>
+ <string name="month_medium_july">7月</string>
+ <string name="month_medium_august">8月</string>
+ <string name="month_medium_september">9月</string>
+ <string name="month_medium_october">10月</string>
+ <string name="month_medium_november">11月</string>
+ <string name="month_medium_december">12月</string>
+
+ <string name="month_shortest_january">1月</string>
+ <string name="month_shortest_february">2月</string>
+ <string name="month_shortest_march">3月</string>
+ <string name="month_shortest_april">4月</string>
+ <string name="month_shortest_may">5月</string>
+ <string name="month_shortest_june">6月</string>
+ <string name="month_shortest_july">7月</string>
+ <string name="month_shortest_august">8月</string>
+ <string name="month_shortest_september">9月</string>
+ <string name="month_shortest_october">10月</string>
+ <string name="month_shortest_november">11月</string>
+ <string name="month_shortest_december">12月</string>
+
+ <string name="day_of_week_long_sunday">星期日</string>
+ <string name="day_of_week_long_monday">星期一</string>
+ <string name="day_of_week_long_tuesday">星期二</string>
+ <string name="day_of_week_long_wednesday">星期三</string>
+ <string name="day_of_week_long_thursday">星期四</string>
+ <string name="day_of_week_long_friday">星期五</string>
+ <string name="day_of_week_long_saturday">星期六</string>
+
+ <string name="day_of_week_medium_sunday">周日</string>
+ <string name="day_of_week_medium_monday">周一</string>
+ <string name="day_of_week_medium_tuesday">周二</string>
+ <string name="day_of_week_medium_wednesday">周三</string>
+ <string name="day_of_week_medium_thursday">周四</string>
+ <string name="day_of_week_medium_friday">周五</string>
+ <string name="day_of_week_medium_saturday">周六</string>
+
+ <string name="day_of_week_short_sunday">周日</string>
+ <string name="day_of_week_short_monday">周一</string>
+ <string name="day_of_week_short_tuesday">周二</string>
+ <string name="day_of_week_short_wednesday">周三</string>
+ <string name="day_of_week_short_thursday">周四</string>
+ <string name="day_of_week_short_friday">周五</string>
+ <string name="day_of_week_short_saturday">周六</string>
+
+ <string name="day_of_week_shortest_sunday">日</string>
+ <string name="day_of_week_shortest_monday">一</string>
+ <string name="day_of_week_shortest_tuesday">二</string>
+ <string name="day_of_week_shortest_wednesday">三</string>
+ <string name="day_of_week_shortest_thursday">四</string>
+ <string name="day_of_week_shortest_friday">五</string>
+ <string name="day_of_week_shortest_saturday">六</string>
+
+ <string name="am">上午</string>
+ <string name="pm">下午</string>
+ <string name="yesterday">昨天</string>
+ <string name="today">今天</string>
+ <string name="tomorrow">明天</string>
+
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="numeric_date">%Y-%-m-%-e</string>
+ <string name="numeric_date_format">yyyy-M-d</string>
+ <string name="month_day_year">%Y年%-m月%-e日</string>
+ <string name="time_of_day">%p%I:%M:%S</string>
+ <string name="date_and_time">%p%I:%M:%S %Y-%-m-%-e</string>
+ <string name="abbrev_month_day_year">%Y-%-m-%-e</string>
+ <string name="month_day">%B%-e日</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y年%B</string>
+ <string name="abbrev_month_day">%b%-e日</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y年%b</string>
+</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 54b0b97..ee7b3cd 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -424,9 +424,6 @@
<string name="lockscreen_glogin_password_hint">"密码"</string>
<string name="lockscreen_glogin_submit_button">"登录"</string>
<string name="lockscreen_glogin_invalid_input">"用户名或密码无效。"</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="AMPM">%P</xliff:g><xliff:g id="HOUR">%-l</xliff:g>点"</string>
<string name="hour_cap_ampm">"<xliff:g id="AMPM">%p</xliff:g><xliff:g id="HOUR">%-l</xliff:g>点"</string>
<string name="status_bar_clear_all_button">"清除通知"</string>
@@ -458,9 +455,6 @@
<string name="menu_enter_shortcut_label">"Enter 键"</string>
<string name="menu_delete_shortcut_label">"删除"</string>
<string name="search_go">"搜索"</string>
- <string name="today">"今天"</string>
- <string name="yesterday">"昨天"</string>
- <string name="tomorrow">"明天"</string>
<string name="oneMonthDurationPast">"1 个月前"</string>
<string name="beforeOneMonthDurationPast">"1 个月前"</string>
<plurals name="num_seconds_ago">
@@ -542,13 +536,6 @@
<string name="weeks">"周"</string>
<string name="year">"年"</string>
<string name="years">"年"</string>
- <string name="sunday">"周日"</string>
- <string name="monday">"周一"</string>
- <string name="tuesday">"周二"</string>
- <string name="wednesday">"周三"</string>
- <string name="thursday">"周四"</string>
- <string name="friday">"周五"</string>
- <string name="saturday">"周六"</string>
<string name="every_weekday">"每个工作日(周一到周五)"</string>
<string name="daily">"每天"</string>
<string name="weekly">"每周的<xliff:g id="DAY">%s</xliff:g>"</string>
@@ -558,9 +545,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"抱歉,该视频不适合在此设备上播放。"</string>
<string name="VideoView_error_text_unknown">"很抱歉,此视频不能播放。"</string>
<string name="VideoView_error_button">"确定"</string>
- <string name="am">"上午"</string>
- <string name="pm">"下午"</string>
- <string name="numeric_date">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%m</xliff:g> 月 <xliff:g id="DAY">%d</xliff:g> 日"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> 至 <xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> 至 <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -572,23 +556,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="DAY">d</xliff:g>' 月 '<xliff:g id="MONTH">MMM</xliff:g>' 日'"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
<string name="Midnight">"午夜"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> 月 <xliff:g id="DAY">%-d</xliff:g> 日"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%B</xliff:g> 月 <xliff:g id="DAY">%-d</xliff:g> 日"</string>
- <string name="month_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%B</xliff:g> 月"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%B</xliff:g> 月 <xliff:g id="DAY">%-d</xliff:g> 日 <xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
@@ -613,82 +586,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%b</xliff:g> 月 <xliff:g id="DAY">%-d</xliff:g> 日"</string>
- <string name="abbrev_month_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%b</xliff:g> 月"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> 月 <xliff:g id="DAY">%-d</xliff:g> 日"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"周日"</string>
- <string name="day_of_week_long_monday">"周一"</string>
- <string name="day_of_week_long_tuesday">"周二"</string>
- <string name="day_of_week_long_wednesday">"周三"</string>
- <string name="day_of_week_long_thursday">"周四"</string>
- <string name="day_of_week_long_friday">"周五"</string>
- <string name="day_of_week_long_saturday">"周六"</string>
- <string name="day_of_week_medium_sunday">"周日"</string>
- <string name="day_of_week_medium_monday">"周一"</string>
- <string name="day_of_week_medium_tuesday">"周二"</string>
- <string name="day_of_week_medium_wednesday">"周三"</string>
- <string name="day_of_week_medium_thursday">"周四"</string>
- <string name="day_of_week_medium_friday">"周五"</string>
- <string name="day_of_week_medium_saturday">"周六"</string>
- <string name="day_of_week_short_sunday">"周日"</string>
- <string name="day_of_week_short_monday">"周一"</string>
- <string name="day_of_week_short_tuesday">"周二"</string>
- <string name="day_of_week_short_wednesday">"周三"</string>
- <string name="day_of_week_short_thursday">"周四"</string>
- <string name="day_of_week_short_friday">"周五"</string>
- <string name="day_of_week_short_saturday">"周六"</string>
- <string name="day_of_week_shorter_sunday">"周日"</string>
- <string name="day_of_week_shorter_monday">"周一"</string>
- <string name="day_of_week_shorter_tuesday">"周二"</string>
- <string name="day_of_week_shorter_wednesday">"周三"</string>
- <string name="day_of_week_shorter_thursday">"周四"</string>
- <string name="day_of_week_shorter_friday">"周五"</string>
- <string name="day_of_week_shorter_saturday">"周六"</string>
- <string name="day_of_week_shortest_sunday">"周日"</string>
- <string name="day_of_week_shortest_monday">"周一"</string>
- <string name="day_of_week_shortest_tuesday">"周二"</string>
- <string name="day_of_week_shortest_wednesday">"周三"</string>
- <string name="day_of_week_shortest_thursday">"周四"</string>
- <string name="day_of_week_shortest_friday">"周五"</string>
- <string name="day_of_week_shortest_saturday">"周六"</string>
- <string name="month_long_january">"1 月"</string>
- <string name="month_long_february">"2 月"</string>
- <string name="month_long_march">"3 月"</string>
- <string name="month_long_april">"4 月"</string>
- <string name="month_long_may">"5 月"</string>
- <string name="month_long_june">"6 月"</string>
- <string name="month_long_july">"7 月"</string>
- <string name="month_long_august">"8 月"</string>
- <string name="month_long_september">"9 月"</string>
- <string name="month_long_october">"10 月"</string>
- <string name="month_long_november">"11 月"</string>
- <string name="month_long_december">"12 月"</string>
- <string name="month_medium_january">"1 月"</string>
- <string name="month_medium_february">"2 月"</string>
- <string name="month_medium_march">"3 月"</string>
- <string name="month_medium_april">"4 月"</string>
- <string name="month_medium_may">"5 月"</string>
- <string name="month_medium_june">"6 月"</string>
- <string name="month_medium_july">"7 月"</string>
- <string name="month_medium_august">"8 月"</string>
- <string name="month_medium_september">"9 月"</string>
- <string name="month_medium_october">"10 月"</string>
- <string name="month_medium_november">"11 月"</string>
- <string name="month_medium_december">"12 月"</string>
- <string name="month_shortest_january">"1 月"</string>
- <string name="month_shortest_february">"2 月"</string>
- <string name="month_shortest_march">"3 月"</string>
- <string name="month_shortest_april">"4 月"</string>
- <string name="month_shortest_may">"5 月"</string>
- <string name="month_shortest_june">"6 月"</string>
- <string name="month_shortest_july">"7 月"</string>
- <string name="month_shortest_august">"8 月"</string>
- <string name="month_shortest_september">"9 月"</string>
- <string name="month_shortest_october">"10 月"</string>
- <string name="month_shortest_november">"11 月"</string>
- <string name="month_shortest_december">"12 月"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"全选"</string>
diff --git a/core/res/res/values-zh-rTW/donottranslate-cldr.xml b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
new file mode 100644
index 0000000..18e37a9
--- /dev/null
+++ b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">一月</string>
+ <string name="month_long_standalone_february">二月</string>
+ <string name="month_long_standalone_march">三月</string>
+ <string name="month_long_standalone_april">四月</string>
+ <string name="month_long_standalone_may">五月</string>
+ <string name="month_long_standalone_june">六月</string>
+ <string name="month_long_standalone_july">七月</string>
+ <string name="month_long_standalone_august">八月</string>
+ <string name="month_long_standalone_september">九月</string>
+ <string name="month_long_standalone_october">十月</string>
+ <string name="month_long_standalone_november">十一月</string>
+ <string name="month_long_standalone_december">十二月</string>
+
+ <string name="month_long_january">1月</string>
+ <string name="month_long_february">2月</string>
+ <string name="month_long_march">3月</string>
+ <string name="month_long_april">4月</string>
+ <string name="month_long_may">5月</string>
+ <string name="month_long_june">6月</string>
+ <string name="month_long_july">7月</string>
+ <string name="month_long_august">8月</string>
+ <string name="month_long_september">9月</string>
+ <string name="month_long_october">10月</string>
+ <string name="month_long_november">11月</string>
+ <string name="month_long_december">12月</string>
+
+ <string name="month_medium_january">1月</string>
+ <string name="month_medium_february">2月</string>
+ <string name="month_medium_march">3月</string>
+ <string name="month_medium_april">4月</string>
+ <string name="month_medium_may">5月</string>
+ <string name="month_medium_june">6月</string>
+ <string name="month_medium_july">7月</string>
+ <string name="month_medium_august">8月</string>
+ <string name="month_medium_september">9月</string>
+ <string name="month_medium_october">10月</string>
+ <string name="month_medium_november">11月</string>
+ <string name="month_medium_december">12月</string>
+
+ <string name="month_shortest_january">1月</string>
+ <string name="month_shortest_february">2月</string>
+ <string name="month_shortest_march">3月</string>
+ <string name="month_shortest_april">4月</string>
+ <string name="month_shortest_may">5月</string>
+ <string name="month_shortest_june">6月</string>
+ <string name="month_shortest_july">7月</string>
+ <string name="month_shortest_august">8月</string>
+ <string name="month_shortest_september">9月</string>
+ <string name="month_shortest_october">10月</string>
+ <string name="month_shortest_november">11月</string>
+ <string name="month_shortest_december">12月</string>
+
+ <string name="day_of_week_long_sunday">星期日</string>
+ <string name="day_of_week_long_monday">星期一</string>
+ <string name="day_of_week_long_tuesday">星期二</string>
+ <string name="day_of_week_long_wednesday">星期三</string>
+ <string name="day_of_week_long_thursday">星期四</string>
+ <string name="day_of_week_long_friday">星期五</string>
+ <string name="day_of_week_long_saturday">星期六</string>
+
+ <string name="day_of_week_medium_sunday">周日</string>
+ <string name="day_of_week_medium_monday">周一</string>
+ <string name="day_of_week_medium_tuesday">周二</string>
+ <string name="day_of_week_medium_wednesday">周三</string>
+ <string name="day_of_week_medium_thursday">周四</string>
+ <string name="day_of_week_medium_friday">周五</string>
+ <string name="day_of_week_medium_saturday">周六</string>
+
+ <string name="day_of_week_short_sunday">周日</string>
+ <string name="day_of_week_short_monday">周一</string>
+ <string name="day_of_week_short_tuesday">周二</string>
+ <string name="day_of_week_short_wednesday">周三</string>
+ <string name="day_of_week_short_thursday">周四</string>
+ <string name="day_of_week_short_friday">周五</string>
+ <string name="day_of_week_short_saturday">周六</string>
+
+ <string name="day_of_week_shortest_sunday">日</string>
+ <string name="day_of_week_shortest_monday">一</string>
+ <string name="day_of_week_shortest_tuesday">二</string>
+ <string name="day_of_week_shortest_wednesday">三</string>
+ <string name="day_of_week_shortest_thursday">四</string>
+ <string name="day_of_week_shortest_friday">五</string>
+ <string name="day_of_week_shortest_saturday">六</string>
+
+ <string name="am">上午</string>
+ <string name="pm">下午</string>
+ <string name="yesterday">昨天</string>
+ <string name="today">今天</string>
+ <string name="tomorrow">明天</string>
+
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="numeric_date">%Y-%-m-%-e</string>
+ <string name="numeric_date_format">yyyy-M-d</string>
+ <string name="month_day_year">%Y年%-m月%-e日</string>
+ <string name="time_of_day">%p%I:%M:%S</string>
+ <string name="date_and_time">%p%I:%M:%S %Y-%-m-%-e</string>
+ <string name="abbrev_month_day_year">%Y-%-m-%-e</string>
+ <string name="month_day">%B%-e日</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%Y年%B</string>
+ <string name="abbrev_month_day">%b%-e日</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%Y年%b</string>
+</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 514e304..a742228 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -418,9 +418,6 @@
<string name="lockscreen_glogin_password_hint">"密碼"</string>
<string name="lockscreen_glogin_submit_button">"登入"</string>
<string name="lockscreen_glogin_invalid_input">"使用者名稱或密碼錯誤。"</string>
- <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
- <string name="hour_minute_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
- <string name="hour_minute_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="hour_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
<string name="hour_cap_ampm">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
<string name="status_bar_clear_all_button">"清除通知"</string>
@@ -452,9 +449,6 @@
<string name="menu_enter_shortcut_label">"輸入"</string>
<string name="menu_delete_shortcut_label">"刪除"</string>
<string name="search_go">"搜尋"</string>
- <string name="today">"今天"</string>
- <string name="yesterday">"昨天"</string>
- <string name="tomorrow">"明天"</string>
<string name="oneMonthDurationPast">"1 個月以前"</string>
<string name="beforeOneMonthDurationPast">"1 個月前"</string>
<plurals name="num_seconds_ago">
@@ -536,13 +530,6 @@
<string name="weeks">"週"</string>
<string name="year">"年"</string>
<string name="years">"年"</string>
- <string name="sunday">"星期日"</string>
- <string name="monday">"星期一"</string>
- <string name="tuesday">"星期二"</string>
- <string name="wednesday">"星期三"</string>
- <string name="thursday">"星期四"</string>
- <string name="friday">"星期五"</string>
- <string name="saturday">"星期六"</string>
<string name="every_weekday">"每天 (週一至週五)"</string>
<string name="daily">"每天"</string>
<string name="weekly">"每週<xliff:g id="DAY">%s</xliff:g>"</string>
@@ -552,9 +539,6 @@
<string name="VideoView_error_text_invalid_progressive_playback">"很抱歉,影片格式無效,裝置無法進行串流處理。"</string>
<string name="VideoView_error_text_unknown">"很抱歉,此影片無法播放。"</string>
<string name="VideoView_error_button">"確定"</string>
- <string name="am">"上午"</string>
- <string name="pm">"下午"</string>
- <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="WEEKDAY2">%4$s</xliff:g>,<xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -566,23 +550,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">HH</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
<string name="Midnight">"午夜"</string>
- <string name="month_day">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g> 日"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="month_day_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g> 日"</string>
- <string name="month_year">"<xliff:g id="YEAR">%Y</xliff:g> 年<xliff:g id="MONTH">%B</xliff:g>"</string>
- <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g> 日,<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
<string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
@@ -607,82 +580,8 @@
<string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g> 日"</string>
- <string name="abbrev_month_year">"<xliff:g id="YEAR">%Y</xliff:g> 年 <xliff:g id="MONTH">%b</xliff:g>"</string>
- <string name="abbrev_month_day">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g> 日"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"星期日"</string>
- <string name="day_of_week_long_monday">"星期一"</string>
- <string name="day_of_week_long_tuesday">"星期二"</string>
- <string name="day_of_week_long_wednesday">"星期三"</string>
- <string name="day_of_week_long_thursday">"星期四"</string>
- <string name="day_of_week_long_friday">"星期五"</string>
- <string name="day_of_week_long_saturday">"星期六"</string>
- <string name="day_of_week_medium_sunday">"週日"</string>
- <string name="day_of_week_medium_monday">"週一"</string>
- <string name="day_of_week_medium_tuesday">"週二"</string>
- <string name="day_of_week_medium_wednesday">"週三"</string>
- <string name="day_of_week_medium_thursday">"週四"</string>
- <string name="day_of_week_medium_friday">"五"</string>
- <string name="day_of_week_medium_saturday">"週六"</string>
- <string name="day_of_week_short_sunday">"日"</string>
- <string name="day_of_week_short_monday">"一"</string>
- <string name="day_of_week_short_tuesday">"二"</string>
- <string name="day_of_week_short_wednesday">"三"</string>
- <string name="day_of_week_short_thursday">"週四"</string>
- <string name="day_of_week_short_friday">"五"</string>
- <string name="day_of_week_short_saturday">"六"</string>
- <string name="day_of_week_shorter_sunday">"日"</string>
- <string name="day_of_week_shorter_monday">"一"</string>
- <string name="day_of_week_shorter_tuesday">"二"</string>
- <string name="day_of_week_shorter_wednesday">"三"</string>
- <string name="day_of_week_shorter_thursday">"四"</string>
- <string name="day_of_week_shorter_friday">"五"</string>
- <string name="day_of_week_shorter_saturday">"六"</string>
- <string name="day_of_week_shortest_sunday">"日"</string>
- <string name="day_of_week_shortest_monday">"一"</string>
- <string name="day_of_week_shortest_tuesday">"二"</string>
- <string name="day_of_week_shortest_wednesday">"三"</string>
- <string name="day_of_week_shortest_thursday">"四"</string>
- <string name="day_of_week_shortest_friday">"五"</string>
- <string name="day_of_week_shortest_saturday">"六"</string>
- <string name="month_long_january">"1 月"</string>
- <string name="month_long_february">"2 月"</string>
- <string name="month_long_march">"3 月"</string>
- <string name="month_long_april">"4 月"</string>
- <string name="month_long_may">"5 月"</string>
- <string name="month_long_june">"6 月"</string>
- <string name="month_long_july">"7 月"</string>
- <string name="month_long_august">"8 月"</string>
- <string name="month_long_september">"9 月"</string>
- <string name="month_long_october">"10 月"</string>
- <string name="month_long_november">"11 月"</string>
- <string name="month_long_december">"12 月"</string>
- <string name="month_medium_january">"1 月"</string>
- <string name="month_medium_february">"2 月"</string>
- <string name="month_medium_march">"3 月"</string>
- <string name="month_medium_april">"4 月"</string>
- <string name="month_medium_may">"5 月"</string>
- <string name="month_medium_june">"6 月"</string>
- <string name="month_medium_july">"7 月"</string>
- <string name="month_medium_august">"8 月"</string>
- <string name="month_medium_september">"9 月"</string>
- <string name="month_medium_october">"10 月"</string>
- <string name="month_medium_november">"11 月"</string>
- <string name="month_medium_december">"12 月"</string>
- <string name="month_shortest_january">"1"</string>
- <string name="month_shortest_february">"2"</string>
- <string name="month_shortest_march">"3"</string>
- <string name="month_shortest_april">"4"</string>
- <string name="month_shortest_may">"5"</string>
- <string name="month_shortest_june">"6"</string>
- <string name="month_shortest_july">"7"</string>
- <string name="month_shortest_august">"8"</string>
- <string name="month_shortest_september">"9"</string>
- <string name="month_shortest_october">"10"</string>
- <string name="month_shortest_november">"11"</string>
- <string name="month_shortest_december">"12"</string>
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<string name="selectAll">"全部選取"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 633a831..052ab35 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -79,6 +79,9 @@
<attr name="textColorPrimaryInverseNoDisable" format="reference|color" />
<!-- Dim inverse text color. This does not differentiate the disabled state. -->
<attr name="textColorSecondaryInverseNoDisable" format="reference|color" />
+
+ <!-- Text color for urls in search suggestions, used by things like global search and the browser. @hide -->
+ <attr name="textColorSearchUrl" format="reference|color" />
<!-- Text color, typeface, size, and style for "large" text. Defaults to primary text color. -->
<attr name="textAppearanceLarge" format="reference" />
@@ -99,6 +102,7 @@
<!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
<attr name="textAppearanceSearchResultSubtitle" format="reference" />
+
<!-- Text color, typeface, size, and style for the text inside of a button. -->
<attr name="textAppearanceButton" format="reference" />
@@ -152,8 +156,8 @@
<!-- The preferred list item height -->
<attr name="listPreferredItemHeight" format="dimension" />
<!-- The drawable for the list divider -->
- <!-- The list item height for search results. @hide -->
- <attr name="searchResultListItemHeight" format="dimension" />
+ <!-- The list item height for search results. @hide -->
+ <attr name="searchResultListItemHeight" format="dimension" />
<attr name="listDivider" format="reference" />
<!-- TextView style for list separators. -->
<attr name="listSeparatorTextViewStyle" format="reference" />
@@ -664,8 +668,8 @@
<!-- A coordinate in the Y dimension. -->
<attr name="y" format="dimension" />
- <!-- Specifies how to place an object, both
- its x and y axis, within a larger containing object. -->
+ <!-- Specifies how to place the content of an object, both
+ on the x and y axis, within the object itself. -->
<attr name="gravity">
<!-- Push object to the top of its container, not changing its size. -->
<flag name="top" value="0x30" />
@@ -721,8 +725,7 @@
<attr name="entries" format="reference" />
<!-- Standard gravity constant that a child can supply to its parent.
- Defines how to place an object, both
- its x and y axis, within a larger containing object. -->
+ Defines how to place the view, both its x and y axis, within its parent view group. -->
<attr name="layout_gravity">
<!-- Push object to the top of its container, not changing its size. -->
<flag name="top" value="0x30" />
@@ -1165,6 +1168,11 @@
enabled for events such as long presses. -->
<attr name="hapticFeedbackEnabled" format="boolean" />
+ <!-- Defines text that briefly describes content of the view. This property is used
+ primarily for accessibility. Since some views do not have textual
+ representation this attribute can be used for providing such. -->
+ <attr name="contentDescription" format="string" localization="suggested" />
+
<!-- Name of the method in this View's context to invoke when the view is
clicked. This name must correspond to a public method that takes
exactly one parameter of type View. For instance, if you specify
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 8150067..96369f4 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -73,5 +73,8 @@
<color name="perms_normal_grp_color">#eeeeee</color>
<color name="perms_normal_perm_color">#c0c0c0</color>
+ <!-- For search-related UIs -->
+ <color name="search_url_text">#7fa87f</color>
+
</resources>
diff --git a/core/res/res/values/donottranslate-cldr.xml b/core/res/res/values/donottranslate-cldr.xml
new file mode 100644
index 0000000..f305948
--- /dev/null
+++ b/core/res/res/values/donottranslate-cldr.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">January</string>
+ <string name="month_long_standalone_february">February</string>
+ <string name="month_long_standalone_march">March</string>
+ <string name="month_long_standalone_april">April</string>
+ <string name="month_long_standalone_may">May</string>
+ <string name="month_long_standalone_june">June</string>
+ <string name="month_long_standalone_july">July</string>
+ <string name="month_long_standalone_august">August</string>
+ <string name="month_long_standalone_september">September</string>
+ <string name="month_long_standalone_october">October</string>
+ <string name="month_long_standalone_november">November</string>
+ <string name="month_long_standalone_december">December</string>
+
+ <string name="month_long_january">January</string>
+ <string name="month_long_february">February</string>
+ <string name="month_long_march">March</string>
+ <string name="month_long_april">April</string>
+ <string name="month_long_may">May</string>
+ <string name="month_long_june">June</string>
+ <string name="month_long_july">July</string>
+ <string name="month_long_august">August</string>
+ <string name="month_long_september">September</string>
+ <string name="month_long_october">October</string>
+ <string name="month_long_november">November</string>
+ <string name="month_long_december">December</string>
+
+ <string name="month_medium_january">Jan</string>
+ <string name="month_medium_february">Feb</string>
+ <string name="month_medium_march">Mar</string>
+ <string name="month_medium_april">Apr</string>
+ <string name="month_medium_may">May</string>
+ <string name="month_medium_june">Jun</string>
+ <string name="month_medium_july">Jul</string>
+ <string name="month_medium_august">Aug</string>
+ <string name="month_medium_september">Sep</string>
+ <string name="month_medium_october">Oct</string>
+ <string name="month_medium_november">Nov</string>
+ <string name="month_medium_december">Dec</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">Sunday</string>
+ <string name="day_of_week_long_monday">Monday</string>
+ <string name="day_of_week_long_tuesday">Tuesday</string>
+ <string name="day_of_week_long_wednesday">Wednesday</string>
+ <string name="day_of_week_long_thursday">Thursday</string>
+ <string name="day_of_week_long_friday">Friday</string>
+ <string name="day_of_week_long_saturday">Saturday</string>
+
+ <string name="day_of_week_medium_sunday">Sun</string>
+ <string name="day_of_week_medium_monday">Mon</string>
+ <string name="day_of_week_medium_tuesday">Tue</string>
+ <string name="day_of_week_medium_wednesday">Wed</string>
+ <string name="day_of_week_medium_thursday">Thu</string>
+ <string name="day_of_week_medium_friday">Fri</string>
+ <string name="day_of_week_medium_saturday">Sat</string>
+
+ <string name="day_of_week_short_sunday">Su</string>
+ <string name="day_of_week_short_monday">Mo</string>
+ <string name="day_of_week_short_tuesday">Tu</string>
+ <string name="day_of_week_short_wednesday">We</string>
+ <string name="day_of_week_short_thursday">Th</string>
+ <string name="day_of_week_short_friday">Fr</string>
+ <string name="day_of_week_short_saturday">Sa</string>
+
+ <string name="day_of_week_shortest_sunday">S</string>
+ <string name="day_of_week_shortest_monday">M</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">W</string>
+ <string name="day_of_week_shortest_thursday">T</string>
+ <string name="day_of_week_shortest_friday">F</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">a.m.</string>
+ <string name="pm">p.m.</string>
+ <string name="yesterday">Yesterday</string>
+ <string name="today">Today</string>
+ <string name="tomorrow">Tomorrow</string>
+
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="numeric_date">%-m/%-e/%Y</string>
+ <string name="numeric_date_format">M/d/yyyy</string>
+ <string name="month_day_year">%B %-e, %Y</string>
+ <string name="time_of_day">%-l:%M:%S %p</string>
+ <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="abbrev_month_day_year">%b %-e, %Y</string>
+ <string name="month_day">%B %-e</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B %Y</string>
+ <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b %Y</string>
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f90c6b8..b5808ea 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1100,6 +1100,7 @@
<public type="attr" name="targetSdkVersion" id="0x01010270" />
<public type="attr" name="maxSdkVersion" id="0x01010271" />
<public type="attr" name="testOnly" id="0x01010272" />
+ <public type="attr" name="contentDescription" id="0x01010273" />
<public type="anim" name="anticipate_interpolator" id="0x010a0007" />
<public type="anim" name="overshoot_interpolator" id="0x010a0008" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 331ef1a..058a445 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -887,7 +887,6 @@
properties uploaded by the checkin service. Not for use by normal
applications.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindGadget">choose widgets</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1070,7 +1069,7 @@
user dictionary.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_sdcardWrite">write to SD card</string>
+ <string name="permlab_sdcardWrite">modify/delete SD card contents</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_sdcardWrite">Allows an application to write to the SD card.</string>
@@ -1096,6 +1095,9 @@
<item>Custom</item>
</string-array>
+ <!-- String which means the type "mobile phone". -->
+ <string name="mobileEmailTypeName">Mobile</string>
+
<!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
<!-- Postal address types from android.provider.Contacts. This could be used when adding a new address for a contact, for example. -->
<string-array name="postalAddressTypes">
@@ -1245,15 +1247,6 @@
<!-- Displayed to the user when unlocking the phone with a username and password fails. -->
<string name="lockscreen_glogin_invalid_input">Invalid username or password.</string>
- <!-- A format string for 12-hour time of day (example: "12:30 PM"). -->
- <string name="status_bar_time_format">"<xliff:g id="hour" example="12">h</xliff:g>:<xliff:g id="minute" example="30">mm</xliff:g> <xliff:g id="ampm" example="AM">AA</xliff:g>"</string>
-
- <!-- A format string for 12-hour time of day, with lower-case "am" or "pm" (example: "12:30pm"). -->
- <string name="hour_minute_ampm">"<xliff:g id="hour" example="12">%-l</xliff:g>:<xliff:g id="minute" example="30">%M</xliff:g><xliff:g id="ampm" example="am">%P</xliff:g>"</string>
-
- <!-- A format string for 12-hour time of day, with capital "AM" or "PM" (example: "12:30PM"). -->
- <string name="hour_minute_cap_ampm">"<xliff:g id="hour" example="12">%-l</xliff:g>:<xliff:g id="minute" example="30">%M</xliff:g><xliff:g id="ampm" example="AM">%p</xliff:g>"</string>
-
<!-- A format string for 12-hour time of day, just the hour, not the minute, with lower-case "am" or "pm" (example: "3pm"). -->
<string name="hour_ampm">"<xliff:g id="hour" example="3">%-l</xliff:g><xliff:g id="ampm" example="pm">%P</xliff:g>"</string>
@@ -1354,12 +1347,6 @@
It is also used by the home screen's search "widget". It should be short -->
<string name="search_go">Search</string>
- <!-- String used to display the date. This is shown instead of a date if the date is today's date. -->
- <string name="today">Today</string>
- <!-- String used to display the date. This is shown instead of a date if the date is yesterday's date. -->
- <string name="yesterday">Yesterday</string>
- <!-- String used to display the date. This is shown instead of a date if the date is tomorrow's date. -->
- <string name="tomorrow">Tomorrow</string>
<!-- String used to display the date. This is the string to say something happened 1 month ago. -->
<string name="oneMonthDurationPast">1 month ago</string>
<!-- String used to display the date. This is the string to say something happened more than 1 month ago. -->
@@ -1493,21 +1480,6 @@
<!-- Appened to express the value is this unit of time. -->
<string name="years">years</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="sunday">Sunday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="monday">Monday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="tuesday">Tuesday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="wednesday">Wednesday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="thursday">Thursday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="friday">Friday</string>
- <!-- Used in the list of which days of the week a calendar event recurrs on -->
- <string name="saturday">Saturday</string>
-
<!-- Calendar spinner item, to select that an event recurs every weekday. -->
<string name="every_weekday">"Every weekday (Mon\u2013Fri)"</string>
<!-- Calendar spinner item, to select that an event recurs every day. -->
@@ -1530,16 +1502,6 @@
<string name="VideoView_error_button">OK</string>
- <!-- AM - as in morning - as in 10:30 AM -->
- <string name="am">"AM"</string>
-
- <!-- PM - as in afternoon - as in 10:30 PM -->
- <string name="pm">"PM"</string>
-
-
- <!-- Numeric form of the day. Example: "12/31/2007" -->
- <string name="numeric_date">"<xliff:g id="month" example="12">%m</xliff:g>/<xliff:g id="day" example="31">%d</xliff:g>/<xliff:g id="year" example="2008">%Y</xliff:g>"</string>
-
<!-- Format indicating a range of time, from a time on one day to a time on another day.
Example: "Mon, Dec 31, 2007, 8am - Tue, Jan 1, 2008, 5pm" -->
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="weekday1" example="Monday">%1$s</xliff:g>, <xliff:g id="date1" example="December 31, 2007">%2$s</xliff:g>, <xliff:g id="time1" example="8am">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Tuesday">%4$s</xliff:g>, <xliff:g id="date2" example="January 1, 2008">%5$s</xliff:g>, <xliff:g id="time2" example="5pm">%6$s</xliff:g>"</string>
@@ -1584,42 +1546,6 @@
Example: "8:00 - 11:00 am, Mon" -->
<string name="time_wday">"<xliff:g id="time_range" example="8:00 - 11:00 am">%1$s</xliff:g>, <xliff:g id="weekday" example="Mon">%2$s</xliff:g>"</string>
- <!-- Date format string used in contexts where the user has said they
- want the month first, as used in the USA, with the month fully
- spelled out. You can remove the comma or add a period,
- or make other punctuation changes appropriate for your locale. -->
- <string name="full_date_month_first" format="date"><xliff:g id="month" example="December">MMMM</xliff:g> <xliff:g id="day" example="31">d</xliff:g>, <xliff:g id="year" example="1972">yyyy</xliff:g></string>
-
- <!-- Date format string used in contexts where the user has said they
- want the day of the month first, as used in Europe, with the month
- fully spelled out. You can remove the comma or add a period,
- or make other punctuation changes appropriate for your locale. -->
- <string name="full_date_day_first" format="date"><xliff:g id="day" example="31">d</xliff:g> <xliff:g id="month" example="December">MMMM</xliff:g>, <xliff:g id="year" example="1972">yyyy</xliff:g></string>
-
- <!-- Date format string used in contexts where the user has said they
- want the month first, as used in the USA, with the month
- abbreviated. You can remove the comma or add a period,
- or make other punctuation changes appropriate for your locale. -->
- <string name="medium_date_month_first" format="date"><xliff:g id="month" example="Dec.">MMM</xliff:g> <xliff:g id="day" example="31">d</xliff:g>, <xliff:g id="year" example="1972">yyyy</xliff:g></string>
-
- <!-- Date format string used in contexts where the user has said they
- want the day of the month first, as used in Europe, with the month
- abbreviated. You can remove the comma or add a period,
- or make other punctuation changes appropriate for your locale. -->
- <string name="medium_date_day_first" format="date"><xliff:g id="day" example="31">d</xliff:g> <xliff:g id="month" example="December">MMM</xliff:g>, <xliff:g id="year" example="1972">yyyy</xliff:g></string>
-
- <!-- Time format string used in the status bar when the user has said they
- want a 12-hour clock with AM and PM.
- You can remove the colon
- or make other punctuation changes appropriate for your locale. -->
- <string name="twelve_hour_time_format" format="date"><xliff:g id="hour" example="11">h</xliff:g>:<xliff:g id="minute" example="59">mm</xliff:g> <xliff:g id="ampm" example="AM">a</xliff:g></string>
-
- <!-- Time format string used in the status bar when the user has said they
- want a 24-hour clock.
- You can remove the colon
- or make other punctuation changes appropriate for your locale. -->
- <string name="twenty_four_hour_time_format" format="date"><xliff:g id="hour" example="23">HH</xliff:g>:<xliff:g id="minute" example="59">mm</xliff:g></string>
-
<!-- Quoted name for 12pm, lowercase -->
<string name="noon">"noon"</string>
<!-- Quoted name for 12pm, uppercase first letter -->
@@ -1629,29 +1555,6 @@
<!-- Quoted name for 12am, uppercase first letter -->
<string name="Midnight">"Midnight"</string>
- <!-- Date format for month and day of month.
- Example: "October 9". -->
- <string name="month_day">"<xliff:g id="month" example="October">%B</xliff:g> <xliff:g id="day" example="9">%-d</xliff:g>"</string>
-
- <!-- Date format for month alone.
- Example: "October" -->
- <string name="month">"<xliff:g id="month" example="October">%B</xliff:g>"</string>
-
- <!-- Date format for month, day, and year.
- Example: "October 9, 2007" -->
- <string name="month_day_year">"<xliff:g id="month" example="October">%B</xliff:g> <xliff:g id="day" example="9">%-d</xliff:g>, <xliff:g id="year" example="2007">%Y</xliff:g>"</string>
-
- <!-- Date format for month and year.
- Example: "October 2007" -->
- <string name="month_year">"<xliff:g id="month" example="October">%B</xliff:g> <xliff:g id="year" example="2007">%Y</xliff:g>"</string>
-
- <!-- A format string for 24-hour time of day (example "23:59"). -->
- <string name="time_of_day">"<xliff:g id="hour" example="23">%H</xliff:g>:<xliff:g id="minute" example="59">%M</xliff:g>:<xliff:g id="second" example="59">%S</xliff:g>"</string>
-
- <!-- Format string for date and 24-hour time of day.
- Example: 23:59:15 Jan 31 2008 -->
- <string name="date_and_time">"<xliff:g id="hour" example="23">%H</xliff:g>:<xliff:g id="minute" example="59">%M</xliff:g>:<xliff:g id="second" example="59">%S</xliff:g> <xliff:g id="month" example="Jan">%B</xliff:g> <xliff:g id="day" example="31">%-d</xliff:g>, <xliff:g id="year" example="2008">%Y</xliff:g>"</string>
-
<!-- Format indicating a range of dates in the same year.
Example: "Oct 31 - Nov 3" -->
<string name="same_year_md1_md2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>"</string>
@@ -1750,312 +1653,7 @@
Example: "Tue, Oct 9, 2007, 8:00am - Wed, Oct 10, 2007, 5:00pm" -->
<string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
- <!-- Format string for abbreviated month, day, and year.
- Example: "Oct 9, 2007" -->
- <string name="abbrev_month_day_year">"<xliff:g id="month" example="Oct">%b</xliff:g> <xliff:g id="day" example="9">%-d</xliff:g>, <xliff:g id="year" example="2007">%Y</xliff:g>"</string>
-
- <!-- Format string for abbreviated month and year.
- Example: "Oct 2007" -->
- <string name="abbrev_month_year">"<xliff:g id="month" example="Oct">%b</xliff:g> <xliff:g id="year" example="2007">%Y</xliff:g>"</string>
-
- <!-- Format string for abbreviated month and day.
- Example: "Oct 9" -->
- <string name="abbrev_month_day">"<xliff:g id="month" example="Oct">%b</xliff:g> <xliff:g id="day" example="31">%-d</xliff:g>"</string>
-
- <!-- Format string for abbreviated month alone.
- Example: "Oct" -->
- <string name="abbrev_month">"<xliff:g id="month" example="Oct">%b</xliff:g>"</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_sunday">Sunday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_monday">Monday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_tuesday">Tuesday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_wednesday">Wednesday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_thursday">Thursday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_friday">Friday</string>
-
- <!-- The full spelled out version of the day of the week. -->
- <string name="day_of_week_long_saturday">Saturday</string>
-
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Sun" stands for Sunday -->
- <string name="day_of_week_medium_sunday">Sun</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Mon" stands for Monday -->
- <string name="day_of_week_medium_monday">Mon</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Tue" stands for Tuesday -->
- <string name="day_of_week_medium_tuesday">Tue</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Wed" stands for Wednesday -->
- <string name="day_of_week_medium_wednesday">Wed</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Thu" stands for Thursday -->
- <string name="day_of_week_medium_thursday">Thu</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Fri" stands for Friday -->
- <string name="day_of_week_medium_friday">Fri</string>
-
- <!-- An abbreviated day of the week. Three characters typically in western languages.
- In US English: "Sat" stands for Saturday -->
- <string name="day_of_week_medium_saturday">Sat</string>
-
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Su" stands for Sunday -->
- <string name="day_of_week_short_sunday">Su</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Mo" stands for Monday -->
- <string name="day_of_week_short_monday">Mo</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Tu" stands for Tuesday -->
- <string name="day_of_week_short_tuesday">Tu</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "We" stands for Wednesday -->
- <string name="day_of_week_short_wednesday">We</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Th" stands for Thursday -->
- <string name="day_of_week_short_thursday">Th</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Fr" stands for Friday -->
- <string name="day_of_week_short_friday">Fr</string>
-
- <!-- An abbreviated day of the week. Two characters typically in western languages.
- In US English: "Sa" stands for Saturday -->
- <string name="day_of_week_short_saturday">Sa</string>
-
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "Su" stands for Sunday -->
- <string name="day_of_week_shorter_sunday">Su</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "M" stands for Monday -->
- <string name="day_of_week_shorter_monday">M</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "Tu" stands for Tuesday -->
- <string name="day_of_week_shorter_tuesday">Tu</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "W" stands for Wednesday -->
- <string name="day_of_week_shorter_wednesday">W</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "Th" stands for Thursday -->
- <string name="day_of_week_shorter_thursday">Th</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "F" stands for Friday -->
- <string name="day_of_week_shorter_friday">F</string>
-
- <!-- An abbreviated day of the week. One character if that is unique. Two if necessary.
- In US English: "Sa" stands for Saturday -->
- <string name="day_of_week_shorter_saturday">Sa</string>
-
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "S" stands for Sunday -->
- <string name="day_of_week_shortest_sunday">S</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "M" stands for Monday -->
- <string name="day_of_week_shortest_monday">M</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "T" stands for Tuesday -->
- <string name="day_of_week_shortest_tuesday">T</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "W" stands for Wednesday -->
- <string name="day_of_week_shortest_wednesday">W</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "T" stands for Thursday -->
- <string name="day_of_week_shortest_thursday">T</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "F" stands for Friday -->
- <string name="day_of_week_shortest_friday">F</string>
-
- <!-- An abbreviated day of the week. One character long if it makes sense. Does not have
- to be unique.
- In US English: "S" stands for Saturday -->
- <string name="day_of_week_shortest_saturday">S</string>
-
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_january">January</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_february">February</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_march">March</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_april">April</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_may">May</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_june">June</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_july">July</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_august">August</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_september">September</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_october">October</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_november">November</string>
-
- <!-- The full spelled out version of the month. -->
- <string name="month_long_december">December</string>
-
-
- <!-- An abbreviated month name.
- In US English: "Jan" stands for January. -->
- <string name="month_medium_january">Jan</string>
-
- <!-- An abbreviated month name.
- In US English: "Feb" stands for February. -->
- <string name="month_medium_february">Feb</string>
-
- <!-- An abbreviated month name.
- In US English: "Mar" stands for March. -->
- <string name="month_medium_march">Mar</string>
-
- <!-- An abbreviated month name.
- In US English: "Apr" stands for April. -->
- <string name="month_medium_april">Apr</string>
-
- <!-- An abbreviated month name.
- In US English: "May" stands for May. -->
- <string name="month_medium_may">May</string>
-
- <!-- An abbreviated month name.
- In US English: "Jun" stands for June. -->
- <string name="month_medium_june">Jun</string>
-
- <!-- An abbreviated month name.
- In US English: "Jul" stands for July. -->
- <string name="month_medium_july">Jul</string>
-
- <!-- An abbreviated month name.
- In US English: "Aug" stands for August. -->
- <string name="month_medium_august">Aug</string>
-
- <!-- An abbreviated month name.
- In US English: "Sep" stands for September. -->
- <string name="month_medium_september">Sep</string>
-
- <!-- An abbreviated month name.
- In US English: "Oct" stands for October. -->
- <string name="month_medium_october">Oct</string>
-
- <!-- An abbreviated month name.
- In US English: "Nov" stands for November. -->
- <string name="month_medium_november">Nov</string>
-
- <!-- An abbreviated month name.
- In US English: "Dec" stands for December. -->
- <string name="month_medium_december">Dec</string>
-
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "J" stands for January -->
- <string name="month_shortest_january">J</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "F" stands for February. -->
- <string name="month_shortest_february">F</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "M" stands for March. -->
- <string name="month_shortest_march">M</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "A" stands for April. -->
- <string name="month_shortest_april">A</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "M" stands for May. -->
- <string name="month_shortest_may">M</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "J" stands for June. -->
- <string name="month_shortest_june">J</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "J" stands for July. -->
- <string name="month_shortest_july">J</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "A" stands for August. -->
- <string name="month_shortest_august">A</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "S" stands for September. -->
- <string name="month_shortest_september">S</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "O" stands for October. -->
- <string name="month_shortest_october">O</string>
-
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "N" stands for November. -->
- <string name="month_shortest_november">N</string>
- <!-- An abbreviated month name. One character long if it makes sense. Does not have
- to be unique.
- In US English: "D" stands for December. -->
- <string name="month_shortest_december">D</string>
<!-- Format string for durations like "01:23" (1 minute, 23 seconds) -->
<string name="elapsed_time_short_format_mm_ss"><xliff:g id="minutes" example="1">%1$02d</xliff:g>:<xliff:g id="seconds" example="23">%2$02d</xliff:g></string>
@@ -2366,10 +1964,12 @@
<!-- This string array should be overridden by the manufacture to present a list of carrier-id,locale pairs. This is used at startup to set a default locale by checking the system property ro.carrier for the carrier-id and searching through this array -->
<string-array translatable="false" name="carrier_locales">
- </string-array>
+ </string-array>
+
+ <!-- Title for the selected state of a CompoundButton. -->
+ <string name="accessibility_compound_button_selected">checked</string>
+
+ <!-- Title for the unselected state of a CompoundButton. -->
+ <string name="accessibility_compound_button_unselected">not checked</string>
+
</resources>
-
-
-
-
-
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a436f61..8160c9c 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -330,7 +330,7 @@
<item name="android:groupIndicator">@android:drawable/expander_group</item>
<item name="android:indicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
<item name="android:indicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
- <item name="android:childDivider">@android:drawable/divider_horizontal_dark</item>
+ <item name="android:childDivider">@android:drawable/divider_horizontal_dark_opaque</item>
</style>
<style name="Widget.ImageWell">
@@ -398,18 +398,18 @@
<style name="Widget.ListView" parent="Widget.AbsListView">
<item name="android:listSelector">@android:drawable/list_selector_background</item>
<item name="android:cacheColorHint">?android:attr/colorBackground</item>
- <item name="android:divider">@android:drawable/divider_horizontal_dark</item>
+ <item name="android:divider">@android:drawable/divider_horizontal_dark_opaque</item>
</style>
<style name="Widget.ListView.White" parent="Widget.AbsListView">
<item name="android:listSelector">@android:drawable/list_selector_background</item>
<item name="android:background">@android:color/white</item>
- <item name="android:divider">@android:drawable/divider_horizontal_bright</item>
+ <item name="android:divider">@android:drawable/divider_horizontal_bright_opaque</item>
</style>
<style name="Widget.ListView.DropDown">
<item name="android:cacheColorHint">@null</item>
- <item name="android:divider">@android:drawable/divider_horizontal_bright</item>
+ <item name="android:divider">@android:drawable/divider_horizontal_bright_opaque</item>
</style>
<style name="Widget.ListView.Menu">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 9567523..b168fb8 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -50,6 +50,7 @@
<item name="textColorSecondaryInverseNoDisable">@android:color/secondary_text_light_nodisable</item>
<item name="textColorHint">@android:color/hint_foreground_dark</item>
<item name="textColorHintInverse">@android:color/hint_foreground_light</item>
+ <item name="textColorSearchUrl">@android:color/search_url_text</item>
<item name="textAppearanceLarge">@android:style/TextAppearance.Large</item>
<item name="textAppearanceMedium">@android:style/TextAppearance.Medium</item>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index f80bd6b..526b6d9 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -54,7 +54,7 @@
<group gid="log" />
</permission>
- <permission name="android.permission.SDCARD_WRITE" >
+ <permission name="android.permission.WRITE_SDCARD" >
<group gid="sdcard_rw" />
</permission>
@@ -84,6 +84,24 @@
others should have a fairly open environment in which to
interact with the system. -->
+ <!-- Standard permissions granted to the shell. -->
+ <assign-permission name="android.permission.WRITE_SDCARD" uid="shell" />
+ <assign-permission name="android.permission.SEND_SMS" uid="shell" />
+ <assign-permission name="android.permission.CALL_PHONE" uid="shell" />
+ <assign-permission name="android.permission.READ_CONTACTS" uid="shell" />
+ <assign-permission name="android.permission.WRITE_CONTACTS" uid="shell" />
+ <assign-permission name="android.permission.READ_OWNER_DATA" uid="shell" />
+ <assign-permission name="android.permission.WRITE_OWNER_DATA" uid="shell" />
+ <assign-permission name="android.permission.READ_CALENDAR" uid="shell" />
+ <assign-permission name="android.permission.WRITE_CALENDAR" uid="shell" />
+ <assign-permission name="android.permission.READ_USER_DICTIONARY" uid="shell" />
+ <assign-permission name="android.permission.WRITE_USER_DICTIONARY" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_FINE_LOCATION" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_COARSE_LOCATION" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_NETWORK_STATE" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_WIFI_STATE" uid="shell" />
+ <assign-permission name="android.permission.BLUETOOTH" uid="shell" />
<!-- System tool permissions granted to the shell. -->
<assign-permission name="android.permission.GET_TASKS" uid="shell" />
<assign-permission name="android.permission.CHANGE_CONFIGURATION" uid="shell" />
@@ -114,6 +132,8 @@
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="shell" />
<assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
<assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
+ <assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
+ <assign-permission name="android.permission.INSTALL_LOCATION_COLLECTOR" uid="shell" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 5367cb2..a044cea 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -95,7 +95,7 @@
</ul>
</li> -->
<!-- <li><a style="color:gray;">Localization</a></li> -->
- <li><a href="<?cs var:toroot ?>guide/topics/appwidgets/index.html">AppWidgets</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/appwidgets/index.html">App Widgets</a></li>
</ul>
</li>
@@ -146,7 +146,7 @@
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/index.html">UI Guidelines</a></div>
<ul>
- <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">Widget Design</a></li>
+ <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">App Widget Design</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/practices/design/performance.html">Designing for Performance</a></li>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index f9db356..01a9648 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -1,4 +1,4 @@
-page.title=AppWidgets
+page.title=App Widgets
@jd:body
<div id="qv-wrapper">
@@ -6,131 +6,338 @@
<h2>Key classes</h2>
<ol>
<li>{@link android.appwidget.AppWidgetProvider}</li>
- <li>{@link android.appwidget.AppWidgetHost}</li>
+ <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
+ <li>{@link android.appwidget.AppWidgetManager}</li>
</ol>
<h2>In this document</h2>
<ol>
- <li><a href="#Providers">AppWidget Providers</a>
+ <li><a href="#Basics">The Basics</a></li>
+ <li><a href="#Manifest">Declaring an App Widget in the Manifest</a></li>
+ <li><a href="#MetaData">Adding the AppWidgetProviderInfo Metadata</a></li>
+ <li><a href="#CreatingLayout">Creating the App Widget Layout</a></li>
+ <li><a href="#AppWidgetProvider">Using the AppWidgetProvider Class</a>
<ol>
- <li><a href="#provider_manifest">Declaring a widget in the AndroidManifest</a></li>
- <li><a href="#provider_meta_data">Adding the AppWidgetProviderInfo meta-data</a></li>
- <li><a href="#provider_AppWidgetProvider">Using the AppWidgetProvider class</a></li>
- <li><a href="#provider_configuration">AppWidget Configuration UI</a></li>
- <li><a href="#provider_broadcasts">AppWidget Broadcast Intents</a></li>
+ <li><a href="#ProviderBroadcasts">Receiving App Widget broadcast Intents</a></li>
</ol>
</li>
- <li><a href="#Hosts">AppWidget Hosts</a></li>
+ <li><a href="#Configuring">Creating an App Widget Configuration Activity</a>
+ <ol>
+ <li><a href="#UpdatingFromTheConfiguration">Updating the App Widget from
+ the configuration Activity</a></li>
+ </ol>
+ </li>
</ol>
<h2>See also</h2>
<ol>
+ <li><a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
+ Guidelines</a></li>
<li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html">Introducing
- home screen widgets and the AppWidget framework »</a></li>
+ home screen widgets and the AppWidget framework »</a></li>
</ol>
</div>
</div>
-<p>AppWidgets are miniature application views that can be embedded in other applications
-(e.g., the Home). These views are called "widgets" and you can publish one with
-an "AppWidget provider." An application component that is able to hold other widgets is
-called an "AppWidget host."</p>
+
+<p>App Widgets are miniature application views that can be embedded in other applications
+(such as the Home screen) and receive periodic updates. These views are referred
+to as Widgets in the user interface,
+and you can publish one with an App Widget provider. An application component that is
+able to hold other App Widgets is called an App Widget host. The screenshot below shows
+the Music App Widget.</p>
+
+<img src="{@docRoot}images/appwidget.png" alt="" />
+
+<p>This document describes how to publish an App Widget using an App Widget provider.</p>
+<h2 id="Basics">The Basics</h2>
+
+<p>To create an App Widget, you need the following:</p>
+
+<dl>
+ <dt>{@link android.appwidget.AppWidgetProviderInfo} object</dt>
+ <dd>Describes the metadata for an App Widget, such as the App Widget's layout, update frequency,
+ and the AppWidgetProvider class. This should be defined in XML.</dd>
+ <dt>{@link android.appwidget.AppWidgetProvider} class implementation</dt>
+ <dd>Defines the basic methods that allow you to programmatically interface with the App Widget,
+ based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated,
+ enabled, disabled and deleted.</dd>
+ <dt>View layout</dt>
+ <dd>Defines the initial layout for the App Widget, defined in XML.</dd>
+</dl>
+
+<p>Additionally, you can implement an App Widget configuration Activity. This is an optional
+{@link android.app.Activity} that launches when the user adds your App Widget and allows him or her
+to modify App Widget settings at create-time.</p>
+
+<p>The following sections describe how to setup each of these components.</p>
-<h2 id="Providers">AppWidget Providers</h2>
-<p>Any application can publish widgets. All an application needs to do to publish a widget is
-to have a {@link android.content.BroadcastReceiver} that receives the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} intent,
-and provide some meta-data about the widget. Android provides the
-{@link android.appwidget.AppWidgetProvider} class, which extends BroadcastReceiver, as a convenience
-class to aid in handling the broadcasts.
+<h2 id="Manifest">Declaring an App Widget in the Manifest</h2>
+<p>First, declare the {@link android.appwidget.AppWidgetProvider} class in your application's
+<code>AndroidManifest.xml</code> file. For example:</p>
-<h3 id="provider_manifest">Declaring a widget in the AndroidManifest</h3>
+<pre>
+<receiver android:name="ExampleAppWidgetProvider" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data android:name="android.appwidget.provider"
+ android:resource="@xml/example_appwidget_info" />
+</receiver>
+</pre>
-<p>First, declare the {@link android.content.BroadcastReceiver} in your application's
-<code>AndroidManifest.xml</code> file.
+<p>The <code><receiver></code> element requires the <code>android:name</code>
+attribute, which specifies the {@link android.appwidget.AppWidgetProvider} used
+by the App Widget.</p>
-{@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/AndroidManifest.xml AppWidgetProvider}
+<p>The <code><intent-filter></code> element must include an <code><action></code>
+element with the <code>android:name</code> attribute. This attribute specifies
+that the {@link android.appwidget.AppWidgetProvider} accepts the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE ACTION_APPWIDGET_UPDATE} broadcast.
+This is the only broadcast that you must explicitly declare. The {@link android.appwidget.AppWidgetManager}
+automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.</p>
-<p>
-The <code><receiver></code> element has the following attributes:
+<p>The <code><meta-data></code> element specifies the
+{@link android.appwidget.AppWidgetProviderInfo} resource and requires the
+following attributes:</p>
<ul>
- <li><code>android:name</code> - specifies the
- {@link android.content.BroadcastReceiver} or {@link android.appwidget.AppWidgetProvider}
- class.</li>
- <li><code>android:label</code> - specifies the string resource that
- will be shown by the widget picker as the label.</li>
- <li><code>android:icon</code> - specifies the drawable resource that
- will be shown by the widget picker as the icon.</li>
-</ul>
-
-<p>
-The <code><intent-filter></code> element tells the {@link android.content.pm.PackageManager}
-that this {@link android.content.BroadcastReceiver} receives the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
-The widget manager will send other broadcasts directly to your widget provider as required.
-It is only necessary to explicitly declare that you accept the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
-
-<p>
-The <code><meta-data></code> element tells the widget manager which xml resource to
-read to find the {@link android.appwidget.AppWidgetProviderInfo} for your widget provider. It has the following
-attributes:
-<ul>
- <li><code>android:name="android.appwidget.provider"</code> - identifies this meta-data
- as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.</li>
- <li><code>android:resource</code> - is the xml resource to use as that descriptor.</li>
+ <li><code>android:name</code> - Specifies the metadata name. Use <code>android.appwidget.provider</code>
+ to identify the data as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.</li>
+ <li><code>android:resource</code> - Specifies the {@link android.appwidget.AppWidgetProviderInfo}
+ resource location.</li>
</ul>
-<h3 id="provider_meta_data">Adding the AppWidgetProviderInfo meta-data</h3>
+<h2 id="MetaData">Adding the AppWidgetProviderInfo Metadata</h2>
-<p>For a widget, the values in the {@link android.appwidget.AppWidgetProviderInfo} structure are supplied
-in an XML resource. In the example above, the xml resource is referenced with
-<code>android:resource="@xml/appwidget_info"</code>. That XML file would go in your application's
-directory at <code>res/xml/appwidget_info.xml</code>. Here is a simple example.
+<p>The {@link android.appwidget.AppWidgetProviderInfo} defines the essential
+qualities of an App Widget, such as its minimum layout dimensions, its initial layout resource,
+how often to update the App Widget, and (optionally) a configuration Activity to launch at create-time.
+Define the AppWidgetProviderInfo object in an XML resource using a single
+<code><appwidget-provider></code> element and save it in the project's <code>res/xml/</code>
+folder.</p>
-{@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/res/xml/appwidget_info.xml AppWidgetProviderInfo}
+<p>For example:</p>
-<p>The attributes are as documented in the
-{@link android.appwidget.AppWidgetProviderInfo} class.
+<pre>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ android:minWidth="294dp" <!-- density-independent pixels -->
+ android:minHeight="72dp"
+ android:updatePeriodMillis="86400000" <!-- once per day -->
+ android:initialLayout="@layout/example_appwidget"
+ android:configure="com.example.android.ExampleAppWidgetConfigure" >
+</appwidget-provider>
+</pre>
+
+<p>Here's a summary of the <code><appwidget-provider></code> attributes:</p>
+<ul>
+ <li>The values for the <code>minWidth</code> and <code>minHeight</code> attributes specify the minimum
+ area required by the App Widget's layout.
+ <p>The default Home screen positions App Widgets in its window based on a grid of
+ cells that have a defined height and width. If the values for an App Widget's minimum width
+ or height don't match the dimensions of the cells,
+ then the App Widget dimensions round <em>up</em> to the nearest cell size.
+ (See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
+ Guidelines</a> for more information on the Home screen cell sizes.)</p>
+ <p>Because the Home screen's layout orientation (and thus, the cell sizes) can change,
+ as a rule of thumb, you should assume the worst-case cell size of 74 pixels for the height
+ <em>and</em> width of a cell. However, you must subtract 2 from the final dimension to account
+ for any integer rounding errors that occur in the pixel count. To find your minimum width
+ and height in density-independent pixels (dp), use this formula:<br/>
+ <code>(number of cells * 74) - 2</code><br/>
+ Following this formula, you should use 72 dp for a height of one cell, 294 dp and for a width of four cells.</p>
+ </li>
+ <li>The <code>updatePerdiodMillis</code> attribute defines how often the App Widget framework should
+ request an update from the {@link android.appwidget.AppWidgetProvider} by calling the
+ {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+ onUpdate()} method. The actual update is not guaranteed to occur exactly on time with this value
+ and we suggest updating as infrequently as possible—perhaps no more than once an hour to
+ conserve the battery. You might also allow the user to adjust the frequency in a
+ configuration—some people might want a stock ticker to update every 15 minutes, or maybe
+ only four times a day.</li>
+ <li>The <code>initialLayout</code> attribute points to the layout resource that defines the
+ App Widget layout.</li>
+ <li>The <code>configure</code> attribute defines the {@link android.app.Activity} to launch when
+ the user adds the App Widget, in order for him or her to configure App Widget properties. This is optional
+ (read <a href="#Configuring">Creating an App Widget Configuration Activity</a> below).</li>
+</ul>
+
+<p>See the {@link android.appwidget.AppWidgetProviderInfo} class for more information on the
+attributes accepted by the <code><appwidget-provider></code> element.</p>
-<h3 id="provider_AppWidgetProvider">Using the AppWidgetProvider class</h3>
+<h2 id="CreatingLayout">Creating the App Widget Layout</h2>
-<p>The AppWidgetProvider class is the easiest way to handle the widget provider intent broadcasts.
-See the <code>src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.java</code>
-sample class in ApiDemos for an example.
+<p>You must define an initial layout for your App Widget in XML and save it in the project's
+<code>res/layout/</code> directory. You can design your App Widget using the View objects listed
+below, but before you begin designing your App Widget, please read and understand the
+<a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
+Guidelines</a>.</p>
-<p class="note">Keep in mind that since the the AppWidgetProvider is a BroadcastReceiver,
-your process is not guaranteed to keep running after the callback methods return. See
-<a href="../../../guide/topics/fundamentals.html#broadlife">Application Fundamentals >
-Broadcast Receiver Lifecycle</a> for more information.
+<p>Creating the App Widget layout is simple if you're
+familiar with <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout in XML</a>.
+However, you must be aware that App Widget layouts are based on {@link android.widget.RemoteViews},
+which do not support every kind of layout or view widget.</p>
+
+<p>A RemoteViews object (and, consequently, an App Widget) can support the
+following layout classes:</p>
+
+<ul class="nolist">
+ <li>{@link android.widget.FrameLayout}</li>
+ <li>{@link android.widget.LinearLayout}</li>
+ <li>{@link android.widget.RelativeLayout}</li>
+</ul>
+
+<p>And the following widget classes:</p>
+<ul class="nolist">
+ <li>{@link android.widget.AnalogClock}</li>
+ <li>{@link android.widget.Button}</li>
+ <li>{@link android.widget.Chronometer}</li>
+ <li>{@link android.widget.ImageButton}</li>
+ <li>{@link android.widget.ImageView}</li>
+ <li>{@link android.widget.ProgressBar}</li>
+ <li>{@link android.widget.TextView}</li>
+</ul>
+
+<p>Descendants of these classes are not supported.</p>
+<h2 id="AppWidgetProvider">Using the AppWidgetProvider Class</h2>
-<h3 id="provider_configuration">AppWidget Configuration UI</h3>
+<div class="sidebox-wrapper">
+ <div class="sidebox-inner">
+ <p>You must declare your AppWidgetProvider class implementation as a broadcast receiver
+ using the <code><receiver></code> element in the AndroidManifest (see
+ <a href="#Manifest">Declaring an App Widget in the Manifest</a> above).</p>
+ </div>
+</div>
-<p>
-Widget hosts have the ability to start a configuration activity when a widget is instantiated.
-The activity should be declared as normal in AndroidManifest.xml, and it should be listed in
-the AppWidgetProviderInfo XML file in the <code>android:configure</code> attribute.
+<p>The {@link android.appwidget.AppWidgetProvider} class extends BroadcastReceiver as a convenience
+class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that
+are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.
+When these broadcast events occur, the AppWidgetProvider receives the following method calls:</p>
-<p>The activity you specified will be launched with the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE} action. See the documentation for that
-action for more info.
+<dl>
+ <dt>{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])}</dt>
+ <dd>This is called to update the App Widget at intervals defined by the <code>updatePeriodMillis</code>
+ attribute in the AppWidgetProviderInfo (see <a href="#MetaData">Adding the
+ AppWidgetProviderInfo Metadata</a> above). This method is also called
+ when the user adds the App Widget, so it should perform the essential setup,
+ such as define event handlers for Views and start a temporary
+ {@link android.app.Service}, if necessary. However, if you have declared a configuration
+ Activity, <strong>this method is not called</strong> when the user adds the App Widget,
+ but is called for the subsequent updates. It is the responsibility of the
+ configuration Activity to perform the first update when configuration is done.
+ (See <a href="#Configuring">Creating an App Widget Configuration Activity</a> below.)</dd>
+ <dt>{@link android.appwidget.AppWidgetProvider#onDeleted(Context,int[])}</dt>
+ <dd>This is called every time an App Widget is deleted from the App Widget host.</dd>
+ <dt>{@link android.appwidget.AppWidgetProvider#onEnabled(Context)}</dt>
+ <dd>This is called when an instance the App Widget is created for the first time. For example, if the user
+ adds two instances of your App Widget, this is only called the first time.
+ If you need to open a new database or perform other setup that only needs to occur once
+ for all App Widget instances, then this is a good place to do it.</dd>
+ <dt>{@link android.appwidget.AppWidgetProvider#onDisabled(Context)}</dt>
+ <dd>This is called when the last instance of your App Widget is deleted from the App Widget host.
+ This is where you should clean up any work done in
+ {@link android.appwidget.AppWidgetProvider#onEnabled(Context)},
+ such as delete a temporary database.</dd>
+ <dt>{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)}</dt>
+ <dd>This is called for every broadcast and before each of the above callback methods.
+ You normally don't need to implement this method because the default AppWidgetProvider
+ implementation filters all App Widget broadcasts and calls the above
+ methods as appropriate.</dd>
+</dl>
-<p>See the <code>src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.java</code>
-sample class in ApiDemos for an example.
+<p class="warning"><strong>Note:</strong> In Android 1.5, there is a known issue in which the
+<code>onDeleted()</code> method will not be called when it should be. To work around this issue,
+you can implement {@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)
+onReceive()} as described in this
+<a href="http://groups.google.com/group/android-developers/msg/e405ca19df2170e2">Group post</a>
+to receive the <code>onDeleted()</code> callback.
+</p>
+
+<p>The most important AppWidgetProvider callback is
+{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+onUpdated()} because it is called when each App Widget is added to a host (unless you use
+a configuration Activity). If your App Widget accepts any
+user interaction events, then you need to register the event handlers in this callback.
+If your App Widget doesn't create temporary
+files or databases, or perform other work that requires clean-up, then
+{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+onUpdated()} may be the only callback method you need to define. For example, if you want an App Widget
+with a button that launches an Activity when clicked, you could use the following
+implementation of AppWidgetProvider:</p>
+
+<pre>
+public class ExampleAppWidgetProvider extends AppWidgetProvider {
+
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+ final int N = appWidgetIds.length;
+
+ // Perform this loop procedure for each App Widget that belongs to this provider
+ for (int i=0; i<N; i++) {
+ int appWidgetId = appWidgetIds[i];
+
+ // Create an Intent to launch ExampleActivity
+ Intent intent = new Intent(context, ExampleActivity.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+
+ // Get the layout for the App Widget and attach an on-click listener to the button
+ RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
+ views.setOnClickPendingIntent(R.id.button, pendingIntent);
+
+ // Tell the AppWidgetManager to perform an update on the current App Widget
+ appWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+ }
+}
+</pre>
+
+<p>This AppWidgetProvider defines only the
+{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+onUpdated()} method for the purpose
+of defining a {@link android.app.PendingIntent} that launches an {@link android.app.Activity}
+and attaching it to the App Widget's button
+with {@link android.widget.RemoteViews#setOnClickPendingIntent(int,PendingIntent)}.
+Notice that it includes a loop that iterates through each entry in <code>appWidgetIds</code>, which
+is an array of IDs that identify each App Widget created by this provider.
+In this way, if the user creates more than one instance of the App Widget, then they are
+all updated simultaneously. However, only one <code>updatePeriodMillis</code> schedule will be
+managed for all instances of the App Widget. For example, if the update schedule is defined
+to be every two hours, and a second instance
+of the App Widget is added one hour after the first one, then they will both be updated
+on the period defined by the first one and the second update period will be ignored
+(they'll both be updated every two hours, not every hour).</p>
+
+<p class="note"><strong>Note:</strong> Because the AppWidgetProvider is a BroadcastReceiver,
+your process is not guaranteed to keep running after the callback methods return (see
+<a href="{@docRoot}guide/topics/fundamentals.html#broadlife">Application Fundamentals >
+Broadcast Receiver Lifecycle</a> for more information). If your App Widget setup process can take several
+seconds (perhaps while performing web requests) and you require that your process continues,
+consider starting a {@link android.app.Service}
+in the {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+onUpdated()} method. From within the Service, you can perform your own updates to the App Widget
+without worrying about the AppWidgetProvider closing down due to an
+<a href="{@docRoot}guide/practices/design/responsiveness.html">Application Not Responding</a>
+(ANR) error. See the
+<a href="http://code.google.com/p/wiktionary-android/source/browse/trunk/Wiktionary/src/com/example/android/wiktionary/WordWidget.java">Wiktionary
+sample's AppWidgetProvider</a> for an example of an App Widget running a {@link android.app.Service}.</p>
+
+<p>Also see the <a
+href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html">
+ExampleAppWidgetProvider.java</a> sample class.</p>
-
-<h3 id="provider_broadcasts">AppWidget Broadcast Intents</h3>
+<h3 id="ProviderBroadcasts">Receiving App Widget broadcast Intents</h3>
<p>{@link android.appwidget.AppWidgetProvider} is just a convenience class. If you would like
-to receive the widget broadcasts directly, you can. The four intents you need to care about are:
+to receive the App Widget broadcasts directly, you can implement your own
+{@link android.content.BroadcastReceiver} or override the
+{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)} callback.
+The four Intents you need to care about are:</p>
<ul>
<li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE}</li>
<li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DELETED}</li>
@@ -138,17 +345,119 @@
<li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DISABLED}</li>
</ul>
-<p>By way of example, the implementation of
-{@link android.appwidget.AppWidgetProvider#onReceive} is quite simple:</p>
-
-{@sample frameworks/base/core/java/android/appwidget/AppWidgetProvider.java onReceive}
-<h2 id="Hosts">AppWidget Hosts</h2>
+<h2 id="Configuring">Creating an App Widget Configuration Activity</h2>
-<p>Widget hosts are the containers in which widgets can be placed. Most of the look and feel
-details are left up to the widget hosts. For example, the home screen has one way of viewing
-widgets, but the lock screen could also contain widgets, and it would have a different way of
-adding, removing and otherwise managing widgets.</p>
-<p>For more information on implementing your own widget host, see the
-{@link android.appwidget.AppWidgetHost AppWidgetHost} class.</p>
+<p>If you would like the user to configure settings when he or she adds a new App Widget,
+you can create an App Widget configuration Activity. This {@link android.app.Activity}
+will be automatically launched by the App Widget host and allows the user to configure
+available settings for the App Widget at create-time, such as the App Widget color, size,
+update period or other functionality settings.</p>
+
+<p>The configuration Activity should be declared as a normal Activity in the Android manifest file.
+However, it will be launched by the App Widget host with the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE ACTION_APPWIDGET_CONFIGURE} action,
+so the Activity needs to accept this Intent. For example:</p>
+
+<pre>
+<activity android:name=".ExampleAppWidgetConfigure">
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+</activity>
+</pre>
+
+<p>Also, the Activity must be declared in the AppWidgetProviderInfo XML file, with the
+<code>android:configure</code> attribute (see <a href="#MetaData">Adding
+the AppWidgetProvierInfo Metadata</a> above). For example, the configuration Activity
+can be declared like this:</p>
+
+<pre>
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+ ...
+ android:configure="com.example.android.ExampleAppWidgetConfigure"
+ ... >
+</appwidget-provider>
+</pre>
+
+<p>Notice that the Activity is declared with a fully-qualified namespace, because
+it will be referenced from outside your package scope.</p>
+
+<p>That's all you need to get started with a configuration Activity. Now all you need is the actual
+Activity. There are, however, two important things to remember when you implement the Activity:</p>
+<ul>
+ <li>The App Widget host calls the configuration Activity and the configuration Activity should always
+ return a result. The result should include the App Widget ID
+ passed by the Intent that launched the Activity (saved in the Intent extras as
+ {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID}).</li>
+ <li>The {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+ onUpdate()} method <strong>will not be called</strong> when the App Widget is created
+ (the system will not send the ACTION_APPWIDGET_UPDATE broadcast when a configuration Activity
+ is launched). It is the responsibility of the configuration Activity to request an update from the
+ AppWidgetManager when the App Widget is first created. However,
+ {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+ onUpdate()} will be called for subsequent updates—it is only skipped the first time.</li>
+</ul>
+
+<p>See the code snippets in the following section for an example of how to return a result
+from the configuration and update the App Widget.</p>
+
+
+<h3 id="UpdatingFromTheConfiguration">Updating the App Widget from the configuration Activity</h3>
+
+<p>When an App Widget uses a configuration Activity, it is the responsibility of the Activity
+to update the App Widget when configuration is complete.
+You can do so by requesting an update directly from the
+{@link android.appwidget.AppWidgetManager}.</p>
+
+<p>Here's a summary of the procedure to properly update the App Widget and close
+the configuration Activity:</p>
+
+<ol>
+ <li>First, get the App Widget ID from the Intent that launched the Activity:
+<pre>
+Intent intent = getIntent();
+Bundle extras = intent.getExtras();
+if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+}
+</pre>
+ </li>
+ <li>Perform your App Widget configuration.</li>
+ <li>When the configuration is complete, get an instance of the AppWidgetManager by calling
+ {@link android.appwidget.AppWidgetManager#getInstance(Context)}:
+<pre>
+AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+</pre>
+ </li>
+ <li>Update the App Widget with a {@link android.widget.RemoteViews} layout by calling
+ {@link android.appwidget.AppWidgetManager#updateAppWidget(int,RemoteViews)}:
+<pre>
+RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
+appWidgetManager.updateAppWidget(mAppWidgetId, views);
+</pre>
+ </li>
+ <li>Finally, create the return Intent, set it with the Activity result, and finish the Activity:</li>
+<pre>
+Intent resultValue = new Intent();
+resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
+setResult(RESULT_OK, resultValue);
+finish();
+</pre>
+ </li>
+</ol>
+
+<p class="note"><strong>Tip:</strong> When your configuration Activity first opens, set
+the Activity result to RESULT_CANCELED. This way, if the user backs-out of the Activity before
+reaching the end, the App Widget host is notified that the configuration was cancelled and the
+App Widget will not be added.</p>
+
+<p>See the <a
+href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.html">
+ExampleAppWidgetConfigure.java</a> sample class in ApiDemos for an example.</p>
+
+
+
diff --git a/docs/html/images/appwidget.png b/docs/html/images/appwidget.png
new file mode 100644
index 0000000..b72b80b
--- /dev/null
+++ b/docs/html/images/appwidget.png
Binary files differ
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 0b398bc..fda584d 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -400,7 +400,7 @@
* @param y The y coordinate of the first pixel in source
* @param width The number of pixels in each row
* @param height The number of rows
- * @param m Option matrix to be applied to the pixels
+ * @param m Optional matrix to be applied to the pixels
* @param filter true if the source should be filtered.
* Only applies if the matrix contains more than just
* translation.
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
index e94c0e8..c11429e 100644
--- a/include/utils/AssetManager.h
+++ b/include/utils/AssetManager.h
@@ -153,6 +153,18 @@
AssetDir* openDir(const char* dirName);
/*
+ * Open a directory within a particular path of the asset manager.
+ *
+ * The contents of the directory are an amalgam of vendor-specific,
+ * locale-specific, and generic assets stored loosely or in asset
+ * packages. Depending on the cache setting and previous accesses,
+ * this call may incur significant disk overhead.
+ *
+ * To open the top-level directory, pass in "".
+ */
+ AssetDir* openNonAssetDir(void* cookie, const char* dirName);
+
+ /*
* Get the type of a file in the asset hierarchy. They will either
* be "regular" or "directory". [Currently only works for "regular".]
*
diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h
index 4c06067..baa3a83 100644
--- a/include/utils/ByteOrder.h
+++ b/include/utils/ByteOrder.h
@@ -38,6 +38,16 @@
* intent is to allow us to avoid byte swapping on the device.
*/
+static inline uint32_t android_swap_long(uint32_t v)
+{
+ return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);
+}
+
+static inline uint16_t android_swap_short(uint16_t v)
+{
+ return (v<<8) | (v>>8);
+}
+
#define DEVICE_BYTE_ORDER LITTLE_ENDIAN
#if BYTE_ORDER == DEVICE_BYTE_ORDER
@@ -49,16 +59,6 @@
#else
-static inline uint32_t android_swap_long(uint32_t v)
-{
- return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);
-}
-
-static inline uint16_t android_swap_short(uint16_t v)
-{
- return (v<<8) | (v>>8);
-}
-
#define dtohl(x) (android_swap_long(x))
#define dtohs(x) (android_swap_short(x))
#define htodl(x) (android_swap_long(x))
@@ -66,4 +66,16 @@
#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define fromlel(x) (x)
+#define fromles(x) (x)
+#define tolel(x) (x)
+#define toles(x) (x)
+#else
+#define fromlel(x) (android_swap_long(x))
+#define fromles(x) (android_swap_short(x))
+#define tolel(x) (android_swap_long(x))
+#define toles(x) (android_swap_short(x))
+#endif
+
#endif // _LIBS_UTILS_BYTE_ORDER_H
diff --git a/include/utils/backup_helpers.h b/include/utils/backup_helpers.h
index 61bee340..0c59fec 100644
--- a/include/utils/backup_helpers.h
+++ b/include/utils/backup_helpers.h
@@ -1,15 +1,128 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#ifndef _UTILS_BACKUP_HELPERS_H
#define _UTILS_BACKUP_HELPERS_H
-int back_up_files(int oldSnapshotFD, int newSnapshotFD, int oldDataStream,
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+namespace android {
+
+int back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
char const* fileBase, char const* const* files, int fileCount);
+// the sizes of all of these match.
+typedef struct {
+ int type; // == APP_MAGIC_V1
+ int packageLen; // length of the name of the package that follows, not including the null.
+ int cookie;
+} app_header_v1;
+
+typedef struct {
+ int type; // ENTITY_MAGIC_V1
+ int keyLen; // length of the key name, not including the null terminator
+ int dataSize; // size of the data, not including the padding
+} entity_header_v1;
+
+typedef struct {
+ int type; // FOOTER_MAGIC_V1
+ int entityCount; // the number of entities that were written
+ int cookie;
+} app_footer_v1;
+
+
+/**
+ * Writes the data.
+ *
+ * If an error occurs, it poisons this object and all write calls will fail
+ * with the error that occurred.
+ */
+class BackupDataWriter
+{
+public:
+ BackupDataWriter(int fd);
+ // does not close fd
+ ~BackupDataWriter();
+
+ status_t WriteAppHeader(const String8& packageName, int cookie);
+
+ status_t WriteEntityHeader(const String8& key, size_t dataSize);
+ status_t WriteEntityData(const void* data, size_t size);
+
+ status_t WriteAppFooter(int cookie);
+
+private:
+ explicit BackupDataWriter();
+ status_t write_padding_for(int n);
+
+ int m_fd;
+ status_t m_status;
+ ssize_t m_pos;
+ int m_entityCount;
+};
+
+/**
+ * Reads the data.
+ *
+ * If an error occurs, it poisons this object and all write calls will fail
+ * with the error that occurred.
+ */
+class BackupDataReader
+{
+public:
+ BackupDataReader(int fd);
+ // does not close fd
+ ~BackupDataReader();
+
+ status_t Status();
+ status_t ReadNextHeader();
+
+ status_t ReadAppHeader(String8* packageName, int* cookie);
+ bool HasEntities();
+ status_t ReadEntityHeader(String8* key, size_t* dataSize);
+ status_t ReadEntityData(void* data, size_t size);
+ status_t ReadAppFooter(int* cookie);
+
+private:
+ explicit BackupDataReader();
+ status_t skip_padding();
+
+ int m_fd;
+ status_t m_status;
+ ssize_t m_pos;
+ int m_entityCount;
+ union {
+ int type;
+ app_header_v1 app;
+ entity_header_v1 entity;
+ app_footer_v1 footer;
+ } m_header;
+};
+
#define TEST_BACKUP_HELPERS 0
#if TEST_BACKUP_HELPERS
int backup_helper_test_empty();
int backup_helper_test_four();
int backup_helper_test_files();
+int backup_helper_test_data_writer();
+int backup_helper_test_data_reader();
#endif
+} // namespace android
+
#endif // _UTILS_BACKUP_HELPERS_H
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index f9fb780..5a1a89b 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -117,7 +117,8 @@
IPermissionController.cpp \
IServiceManager.cpp \
Unicode.cpp \
- file_backup_helper.cpp
+ backup_data.cpp \
+ backup_helper_file.cpp
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_SRC_FILES += $(hostSources)
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index 447b801..4126bfb 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -901,6 +901,60 @@
}
/*
+ * Open a directory in the non-asset namespace.
+ *
+ * An "asset directory" is simply the combination of all files in all
+ * locations, with ".gz" stripped for loose files. With app, locale, and
+ * vendor defined, we have 8 directories and 2 Zip archives to scan.
+ *
+ * Pass in "" for the root dir.
+ */
+AssetDir* AssetManager::openNonAssetDir(void* cookie, const char* dirName)
+{
+ AutoMutex _l(mLock);
+
+ AssetDir* pDir = NULL;
+ SortedVector<AssetDir::FileInfo>* pMergedInfo = NULL;
+
+ LOG_FATAL_IF(mAssetPaths.size() == 0, "No assets added to AssetManager");
+ assert(dirName != NULL);
+
+ //printf("+++ openDir(%s) in '%s'\n", dirName, (const char*) mAssetBase);
+
+ if (mCacheMode != CACHE_OFF && !mCacheValid)
+ loadFileNameCacheLocked();
+
+ pDir = new AssetDir;
+
+ pMergedInfo = new SortedVector<AssetDir::FileInfo>;
+
+ const size_t which = ((size_t)cookie)-1;
+
+ if (which < mAssetPaths.size()) {
+ const asset_path& ap = mAssetPaths.itemAt(which);
+ if (ap.type == kFileTypeRegular) {
+ LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+ scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
+ } else {
+ LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+ scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
+ }
+ }
+
+#if 0
+ printf("FILE LIST:\n");
+ for (i = 0; i < (size_t) pMergedInfo->size(); i++) {
+ printf(" %d: (%d) '%s'\n", i,
+ pMergedInfo->itemAt(i).getFileType(),
+ (const char*) pMergedInfo->itemAt(i).getFileName());
+ }
+#endif
+
+ pDir->setFileList(pMergedInfo);
+ return pDir;
+}
+
+/*
* Scan the contents of the specified directory and merge them into the
* "pMergedInfo" vector, removing previous entries if we find "exclude"
* directives.
@@ -1143,6 +1197,7 @@
LOGE("ARGH: name too long?\n");
continue;
}
+ //printf("Comparing %s in %s?\n", nameBuf, dirName.string());
if (dirNameLen == 0 ||
(strncmp(nameBuf, dirName.string(), dirNameLen) == 0 &&
nameBuf[dirNameLen] == '/'))
@@ -1165,7 +1220,7 @@
createZipSourceNameLocked(zipName, dirName, info.getFileName()));
contents.add(info);
- //printf("FOUND: file '%s'\n", (const char*) info.mFileName);
+ //printf("FOUND: file '%s'\n", info.getFileName().string());
} else {
/* this is a subdir; add it if we don't already have it*/
String8 subdirName(cp, nextSlash - cp);
@@ -1181,7 +1236,7 @@
dirs.add(subdirName);
}
- //printf("FOUND: dir '%s'\n", (const char*) subdirName);
+ //printf("FOUND: dir '%s'\n", subdirName.string());
}
}
}
diff --git a/libs/utils/backup_data.cpp b/libs/utils/backup_data.cpp
new file mode 100644
index 0000000..dd04449
--- /dev/null
+++ b/libs/utils/backup_data.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "backup_data"
+
+#include <utils/backup_helpers.h>
+#include <utils/ByteOrder.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+
+namespace android {
+
+/*
+ * File Format (v1):
+ *
+ * All ints are stored little-endian.
+ *
+ * - An app_header_v1 struct.
+ * - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
+ * - A sequence of zero or more key/value paires (entities), each with
+ * - A entity_header_v1 struct
+ * - The key, utf-8, null terminated, padded to 4-byte boundary.
+ * - The value, padded to 4 byte boundary
+ */
+
+#define APP_MAGIC_V1 0x31707041 // App1 (little endian)
+#define ENTITY_MAGIC_V1 0x61746144 // Data (little endian)
+#define FOOTER_MAGIC_V1 0x746f6f46 // Foot (little endian)
+
+const static int ROUND_UP[4] = { 0, 3, 2, 1 };
+
+static inline size_t
+round_up(size_t n)
+{
+ return n + ROUND_UP[n % 4];
+}
+
+static inline size_t
+padding_extra(size_t n)
+{
+ return ROUND_UP[n % 4];
+}
+
+BackupDataWriter::BackupDataWriter(int fd)
+ :m_fd(fd),
+ m_status(NO_ERROR),
+ m_pos(0),
+ m_entityCount(0)
+{
+}
+
+BackupDataWriter::~BackupDataWriter()
+{
+}
+
+// Pad out anything they've previously written to the next 4 byte boundary.
+status_t
+BackupDataWriter::write_padding_for(int n)
+{
+ ssize_t amt;
+ ssize_t paddingSize;
+
+ paddingSize = padding_extra(n);
+ if (paddingSize > 0) {
+ uint32_t padding = 0xbcbcbcbc;
+ amt = write(m_fd, &padding, paddingSize);
+ if (amt != paddingSize) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+ }
+ return NO_ERROR;
+}
+
+status_t
+BackupDataWriter::WriteAppHeader(const String8& packageName, int cookie)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+
+ ssize_t amt;
+
+ amt = write_padding_for(m_pos);
+ if (amt != 0) {
+ return amt;
+ }
+
+ app_header_v1 header;
+ ssize_t nameLen;
+
+ nameLen = packageName.length();
+
+ header.type = tolel(APP_MAGIC_V1);
+ header.packageLen = tolel(nameLen);
+ header.cookie = cookie;
+
+ amt = write(m_fd, &header, sizeof(app_header_v1));
+ if (amt != sizeof(app_header_v1)) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+
+ amt = write(m_fd, packageName.string(), nameLen+1);
+ if (amt != nameLen+1) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+
+ return NO_ERROR;
+}
+
+status_t
+BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+
+ ssize_t amt;
+
+ amt = write_padding_for(m_pos);
+ if (amt != 0) {
+ return amt;
+ }
+
+ entity_header_v1 header;
+ ssize_t keyLen;
+
+ keyLen = key.length();
+
+ header.type = tolel(ENTITY_MAGIC_V1);
+ header.keyLen = tolel(keyLen);
+ header.dataSize = tolel(dataSize);
+
+ amt = write(m_fd, &header, sizeof(entity_header_v1));
+ if (amt != sizeof(entity_header_v1)) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+
+ amt = write(m_fd, key.string(), keyLen+1);
+ if (amt != keyLen+1) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+
+ amt = write_padding_for(keyLen+1);
+
+ m_entityCount++;
+
+ return amt;
+}
+
+status_t
+BackupDataWriter::WriteEntityData(const void* data, size_t size)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+
+ // We don't write padding here, because they're allowed to call this several
+ // times with smaller buffers. We write it at the end of WriteEntityHeader
+ // instead.
+ ssize_t amt = write(m_fd, data, size);
+ if (amt != (ssize_t)size) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+ return NO_ERROR;
+}
+
+status_t
+BackupDataWriter::WriteAppFooter(int cookie)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+
+ ssize_t amt;
+
+ amt = write_padding_for(m_pos);
+ if (amt != 0) {
+ return amt;
+ }
+
+ app_footer_v1 footer;
+ ssize_t nameLen;
+
+ footer.type = tolel(FOOTER_MAGIC_V1);
+ footer.entityCount = tolel(m_entityCount);
+ footer.cookie = cookie;
+
+ amt = write(m_fd, &footer, sizeof(app_footer_v1));
+ if (amt != sizeof(app_footer_v1)) {
+ m_status = errno;
+ return m_status;
+ }
+ m_pos += amt;
+
+ return NO_ERROR;
+}
+
+
+BackupDataReader::BackupDataReader(int fd)
+ :m_fd(fd),
+ m_status(NO_ERROR),
+ m_pos(0),
+ m_entityCount(0)
+{
+ memset(&m_header, 0, sizeof(m_header));
+}
+
+BackupDataReader::~BackupDataReader()
+{
+}
+
+status_t
+BackupDataReader::Status()
+{
+ return m_status;
+}
+
+#define CHECK_SIZE(actual, expected) \
+ do { \
+ if ((actual) != (expected)) { \
+ if ((actual) == 0) { \
+ m_status = EIO; \
+ } else { \
+ m_status = errno; \
+ } \
+ return m_status; \
+ } \
+ } while(0)
+#define SKIP_PADDING() \
+ do { \
+ status_t err = skip_padding(); \
+ if (err != NO_ERROR) { \
+ m_status = err; \
+ return err; \
+ } \
+ } while(0)
+
+status_t
+BackupDataReader::ReadNextHeader()
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+
+ int amt;
+
+ SKIP_PADDING();
+ amt = read(m_fd, &m_header, sizeof(m_header));
+ CHECK_SIZE(amt, sizeof(m_header));
+
+ // validate and fix up the fields.
+ m_header.type = fromlel(m_header.type);
+ switch (m_header.type)
+ {
+ case APP_MAGIC_V1:
+ m_header.app.packageLen = fromlel(m_header.app.packageLen);
+ if (m_header.app.packageLen < 0) {
+ LOGD("App header at %d has packageLen<0: 0x%08x\n", (int)m_pos,
+ (int)m_header.app.packageLen);
+ m_status = EINVAL;
+ }
+ m_header.app.cookie = m_header.app.cookie;
+ break;
+ case ENTITY_MAGIC_V1:
+ m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
+ if (m_header.entity.keyLen <= 0) {
+ LOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
+ (int)m_header.entity.keyLen);
+ m_status = EINVAL;
+ }
+ m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
+ if (m_header.entity.dataSize < 0) {
+ LOGD("Entity header at %d has dataSize<0: 0x%08x\n", (int)m_pos,
+ (int)m_header.entity.dataSize);
+ m_status = EINVAL;
+ }
+ m_entityCount++;
+ break;
+ case FOOTER_MAGIC_V1:
+ m_header.footer.entityCount = fromlel(m_header.footer.entityCount);
+ if (m_header.footer.entityCount < 0) {
+ LOGD("Entity header at %d has entityCount<0: 0x%08x\n", (int)m_pos,
+ (int)m_header.footer.entityCount);
+ m_status = EINVAL;
+ }
+ m_header.footer.cookie = m_header.footer.cookie;
+ break;
+ default:
+ LOGD("Chunk header at %d has invalid type: 0x%08x", (int)m_pos, (int)m_header.type);
+ m_status = EINVAL;
+ }
+ m_pos += sizeof(m_header);
+
+ return m_status;
+}
+
+status_t
+BackupDataReader::ReadAppHeader(String8* packageName, int* cookie)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+ if (m_header.type != APP_MAGIC_V1) {
+ return EINVAL;
+ }
+ size_t size = m_header.app.packageLen;
+ char* buf = packageName->lockBuffer(size);
+ if (packageName == NULL) {
+ packageName->unlockBuffer();
+ m_status = ENOMEM;
+ return m_status;
+ }
+ int amt = read(m_fd, buf, size+1);
+ CHECK_SIZE(amt, (int)size+1);
+ packageName->unlockBuffer(size);
+ m_pos += size+1;
+ *cookie = m_header.app.cookie;
+ return NO_ERROR;
+}
+
+bool
+BackupDataReader::HasEntities()
+{
+ return m_status == NO_ERROR && m_header.type == ENTITY_MAGIC_V1;
+}
+
+status_t
+BackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+ if (m_header.type != ENTITY_MAGIC_V1) {
+ return EINVAL;
+ }
+ size_t size = m_header.app.packageLen;
+ char* buf = key->lockBuffer(size);
+ if (key == NULL) {
+ key->unlockBuffer();
+ m_status = ENOMEM;
+ return m_status;
+ }
+ int amt = read(m_fd, buf, size+1);
+ CHECK_SIZE(amt, (int)size+1);
+ key->unlockBuffer(size);
+ m_pos += size+1;
+ *dataSize = m_header.entity.dataSize;
+ SKIP_PADDING();
+ return NO_ERROR;
+}
+
+status_t
+BackupDataReader::ReadEntityData(void* data, size_t size)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+ int amt = read(m_fd, data, size);
+ CHECK_SIZE(amt, (int)size);
+ m_pos += size;
+ return NO_ERROR;
+}
+
+status_t
+BackupDataReader::ReadAppFooter(int* cookie)
+{
+ if (m_status != NO_ERROR) {
+ return m_status;
+ }
+ if (m_header.type != FOOTER_MAGIC_V1) {
+ return EINVAL;
+ }
+ if (m_header.footer.entityCount != m_entityCount) {
+ LOGD("entity count mismatch actual=%d expected=%d", m_entityCount,
+ m_header.footer.entityCount);
+ m_status = EINVAL;
+ return m_status;
+ }
+ *cookie = m_header.footer.cookie;
+ return NO_ERROR;
+}
+
+status_t
+BackupDataReader::skip_padding()
+{
+ ssize_t amt;
+ ssize_t paddingSize;
+
+ paddingSize = padding_extra(m_pos);
+ if (paddingSize > 0) {
+ uint32_t padding;
+ amt = read(m_fd, &padding, paddingSize);
+ CHECK_SIZE(amt, paddingSize);
+ m_pos += amt;
+ }
+ return NO_ERROR;
+}
+
+
+} // namespace android
diff --git a/libs/utils/file_backup_helper.cpp b/libs/utils/backup_helper_file.cpp
similarity index 64%
rename from libs/utils/file_backup_helper.cpp
rename to libs/utils/backup_helper_file.cpp
index 111f88d..bf56945 100644
--- a/libs/utils/file_backup_helper.cpp
+++ b/libs/utils/backup_helper_file.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#define LOG_TAG "file_backup_helper"
#include <utils/backup_helpers.h>
@@ -19,11 +35,17 @@
#include <cutils/log.h>
-using namespace android;
+namespace android {
#define MAGIC0 0x70616e53 // Snap
#define MAGIC1 0x656c6946 // File
+#if TEST_BACKUP_HELPERS
+#define LOGP(x...) printf(x)
+#else
+#define LOGP(x...) LOGD(x)
+#endif
+
struct SnapshotHeader {
int magic0;
int fileCount;
@@ -115,6 +137,8 @@
bytesWritten += sizeof(FileState) + round_up(name.length());
}
+ LOGP("write_snapshot_file fd=%d\n", fd);
+
int amt;
SnapshotHeader header = { MAGIC0, N, MAGIC1, bytesWritten };
@@ -159,14 +183,14 @@
static int
write_delete_file(const String8& key)
{
- printf("write_delete_file %s\n", key.string());
+ LOGP("write_delete_file %s\n", key.string());
return 0;
}
static int
write_update_file(const String8& realFilename, const String8& key)
{
- printf("write_update_file %s (%s)\n", realFilename.string(), key.string());
+ LOGP("write_update_file %s (%s)\n", realFilename.string(), key.string());
return 0;
}
@@ -195,7 +219,7 @@
}
int
-back_up_files(int oldSnapshotFD, int newSnapshotFD, int oldDataStream,
+back_up_files(int oldSnapshotFD, int oldDataStream, int newSnapshotFD,
char const* fileBase, char const* const* files, int fileCount)
{
int err;
@@ -245,11 +269,13 @@
// file added
String8 realFilename(base);
realFilename.appendPath(q);
+ LOGP("file added: %s\n", realFilename.string());
write_update_file(realFilename, q);
m++;
}
else if (cmp < 0) {
// file removed
+ LOGP("file removed: %s\n", p.string());
write_delete_file(p);
n++;
}
@@ -260,10 +286,10 @@
const FileState& f = oldSnapshot.valueAt(n);
const FileState& g = newSnapshot.valueAt(m);
- printf("%s\n", q.string());
- printf(" new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+ LOGP("%s\n", q.string());
+ LOGP(" new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
- printf(" old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+ LOGP(" old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
|| f.size != g.size || f.crc32 != g.crc32) {
@@ -570,6 +596,266 @@
return matched ? 0 : 1;
}
+// hexdump -v -e '" " 8/1 " 0x%02x," "\n"' data_writer.data
+const unsigned char DATA_GOLDEN_FILE[] = {
+ 0x41, 0x70, 0x70, 0x31, 0x0b, 0x00, 0x00, 0x00,
+ 0xdd, 0xcc, 0xbb, 0xaa, 0x6e, 0x6f, 0x5f, 0x70,
+ 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
+ 0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
+ 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
+ 0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
+ 0x6e, 0x67, 0x5f, 0x00, 0x41, 0x70, 0x70, 0x31,
+ 0x0c, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
+ 0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+ 0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
+ 0x44, 0x61, 0x74, 0x61, 0x0c, 0x00, 0x00, 0x00,
+ 0x0d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
+ 0x00, 0xbc, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
+ 0x00, 0xbc, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
+ 0x0d, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
+ 0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+ 0x6f, 0x5f, 0x32, 0x5f, 0x5f, 0x00, 0xbc, 0xbc,
+ 0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
+ 0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
+ 0x5f, 0x00, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
+ 0x0a, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
+ 0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+ 0x6f, 0x31, 0x00, 0xbc, 0x44, 0x61, 0x74, 0x61,
+ 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+ 0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
+ 0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00, 0xbc,
+ 0x46, 0x6f, 0x6f, 0x74, 0x04, 0x00, 0x00, 0x00,
+ 0x99, 0x99, 0x77, 0x77
+};
+const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
+
+static int
+test_write_header_and_entity(BackupDataWriter& writer, const char* str)
+{
+ int err;
+ String8 text(str);
+
+ err = writer.WriteAppHeader(text, 0xaabbccdd);
+ if (err != 0) {
+ fprintf(stderr, "WriteAppHeader failed with %s\n", strerror(err));
+ return err;
+ }
+
+ err = writer.WriteEntityHeader(text, text.length()+1);
+ if (err != 0) {
+ fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
+ return err;
+ }
+
+ err = writer.WriteEntityData(text.string(), text.length()+1);
+ if (err != 0) {
+ fprintf(stderr, "write failed for data '%s'\n", text.string());
+ return errno;
+ }
+
+ return err;
+}
+
+int
+backup_helper_test_data_writer()
+{
+ int err;
+ int fd;
+ const char* filename = SCRATCH_DIR "data_writer.data";
+
+ system("rm -r " SCRATCH_DIR);
+ mkdir(SCRATCH_DIR, 0777);
+ mkdir(SCRATCH_DIR "data", 0777);
+
+ fd = creat(filename, 0666);
+ if (fd == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ BackupDataWriter writer(fd);
+
+ err = 0;
+ err |= test_write_header_and_entity(writer, "no_padding_");
+ err |= test_write_header_and_entity(writer, "padded_to__3");
+ err |= test_write_header_and_entity(writer, "padded_to_2__");
+ err |= test_write_header_and_entity(writer, "padded_to1");
+
+ writer.WriteAppFooter(0x77779999);
+
+ close(fd);
+
+ err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
+ if (err != 0) {
+ return err;
+ }
+
+ return err;
+}
+
+int
+test_read_header_and_entity(BackupDataReader& reader, const char* str)
+{
+ int err;
+ int bufSize = strlen(str)+1;
+ char* buf = (char*)malloc(bufSize);
+ String8 string;
+ int cookie = 0x11111111;
+ size_t actualSize;
+
+ // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
+
+ err = reader.ReadNextHeader();
+ if (err != 0) {
+ fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
+ goto done;
+ }
+
+ err = reader.ReadAppHeader(&string, &cookie);
+ if (err != 0) {
+ fprintf(stderr, "ReadAppHeader failed with %s\n", strerror(err));
+ goto done;
+ }
+ if (string != str) {
+ fprintf(stderr, "ReadAppHeader expected packageName '%s' got '%s'\n", str, string.string());
+ err = EINVAL;
+ goto done;
+ }
+ if (cookie != (int)0xaabbccdd) {
+ fprintf(stderr, "ReadAppHeader expected cookie 0x%08x got 0x%08x\n", 0xaabbccdd, cookie);
+ err = EINVAL;
+ goto done;
+ }
+
+ err = reader.ReadNextHeader();
+ if (err != 0) {
+ fprintf(stderr, "ReadNextHeader (for entity header) failed with %s\n", strerror(err));
+ goto done;
+ }
+
+ err = reader.ReadEntityHeader(&string, &actualSize);
+ if (err != 0) {
+ fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
+ goto done;
+ }
+ if (string != str) {
+ fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
+ err = EINVAL;
+ goto done;
+ }
+ if ((int)actualSize != bufSize) {
+ fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
+ actualSize);
+ err = EINVAL;
+ goto done;
+ }
+
+ err = reader.ReadEntityData(buf, bufSize);
+ if (err != NO_ERROR) {
+ fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
+ goto done;
+ }
+
+ if (0 != memcmp(buf, str, bufSize)) {
+ fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
+ "%02x %02x %02x %02x\n", str, buf[0], buf[1], buf[2], buf[3]);
+ err = EINVAL;
+ goto done;
+ }
+
+ // The next read will confirm whether it got the right amount of data.
+
+done:
+ if (err != NO_ERROR) {
+ fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
+ }
+ free(buf);
+ return err;
+}
+
+int
+backup_helper_test_data_reader()
+{
+ int err;
+ int fd;
+ const char* filename = SCRATCH_DIR "data_reader.data";
+
+ system("rm -r " SCRATCH_DIR);
+ mkdir(SCRATCH_DIR, 0777);
+ mkdir(SCRATCH_DIR "data", 0777);
+
+ fd = creat(filename, 0666);
+ if (fd == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
+ if (err != DATA_GOLDEN_FILE_SIZE) {
+ fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
+ return errno;
+ }
+
+ close(fd);
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
+ filename);
+ return errno;
+ }
+
+ {
+ BackupDataReader reader(fd);
+
+ err = 0;
+
+ if (err == NO_ERROR) {
+ err = test_read_header_and_entity(reader, "no_padding_");
+ }
+
+ if (err == NO_ERROR) {
+ err = test_read_header_and_entity(reader, "padded_to__3");
+ }
+
+ if (err == NO_ERROR) {
+ err = test_read_header_and_entity(reader, "padded_to_2__");
+ }
+
+ if (err == NO_ERROR) {
+ err = test_read_header_and_entity(reader, "padded_to1");
+ }
+
+ if (err == NO_ERROR) {
+ err = reader.ReadNextHeader();
+ if (err != 0) {
+ fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
+ }
+
+ if (err == NO_ERROR) {
+ int cookie;
+ err |= reader.ReadAppFooter(&cookie);
+ if (cookie != 0x77779999) {
+ fprintf(stderr, "app footer cookie expected=0x%08x actual=0x%08x\n",
+ 0x77779999, cookie);
+ err = EINVAL;
+ }
+ }
+ }
+ }
+
+ close(fd);
+
+ return err;
+}
+
static int
get_mod_time(const char* filename, struct timeval times[2])
{
@@ -591,8 +877,9 @@
backup_helper_test_files()
{
int err;
- int newSnapshotFD;
int oldSnapshotFD;
+ int dataStreamFD;
+ int newSnapshotFD;
system("rm -r " SCRATCH_DIR);
mkdir(SCRATCH_DIR, 0777);
@@ -613,17 +900,24 @@
"data/f"
};
+ dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
+ if (dataStreamFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
if (newSnapshotFD == -1) {
fprintf(stderr, "error creating: %s\n", strerror(errno));
return errno;
}
-
- err = back_up_files(-1, newSnapshotFD, 0, SCRATCH_DIR, files_before, 5);
+
+ err = back_up_files(-1, dataStreamFD, newSnapshotFD, SCRATCH_DIR, files_before, 5);
if (err != 0) {
return err;
}
+ close(dataStreamFD);
close(newSnapshotFD);
sleep(3);
@@ -662,21 +956,30 @@
return errno;
}
+ dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
+ if (dataStreamFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
if (newSnapshotFD == -1) {
fprintf(stderr, "error creating: %s\n", strerror(errno));
return errno;
}
- err = back_up_files(oldSnapshotFD, newSnapshotFD, 0, SCRATCH_DIR, files_after, 6);
+ err = back_up_files(oldSnapshotFD, dataStreamFD, newSnapshotFD, SCRATCH_DIR, files_after, 6);
if (err != 0) {
return err;
}
close(oldSnapshotFD);
+ close(dataStreamFD);
close(newSnapshotFD);
return 0;
}
#endif // TEST_BACKUP_HELPERS
+
+}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 943d56c..565859c 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -160,11 +160,14 @@
private long mStatusUpdateTime = SystemClock.elapsedRealtime();
// turn off GPS fix icon if we haven't received a fix in 10 seconds
- private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
+ private static final long RECENT_FIX_TIMEOUT = 10;
// number of fixes to receive before disabling GPS
private static final int MIN_FIX_COUNT = 10;
+ // stop trying if we do not receive a fix within 60 seconds
+ private static final int NO_FIX_TIMEOUT = 60;
+
// true if we are enabled
private boolean mEnabled;
@@ -221,8 +224,10 @@
// Alarms
private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
+ private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
private final AlarmManager mAlarmManager;
private final PendingIntent mWakeupIntent;
+ private final PendingIntent mTimeoutIntent;
private final IBatteryStats mBatteryStats;
private final SparseIntArray mClientUids = new SparseIntArray();
@@ -292,6 +297,9 @@
if (action.equals(ALARM_WAKEUP)) {
if (DEBUG) Log.d(TAG, "ALARM_WAKEUP");
startNavigating();
+ } else if (action.equals(ALARM_TIMEOUT)) {
+ if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT");
+ hibernate();
} else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
String state = intent.getStringExtra(Phone.STATE_KEY);
String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
@@ -326,9 +334,11 @@
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
+ mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ALARM_WAKEUP);
+ intentFilter.addAction(ALARM_TIMEOUT);
intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
context.registerReceiver(mBroadcastReciever, intentFilter);
@@ -569,6 +579,7 @@
startNavigating();
} else {
mAlarmManager.cancel(mWakeupIntent);
+ mAlarmManager.cancel(mTimeoutIntent);
stopNavigating();
}
}
@@ -672,12 +683,19 @@
if (!native_start(mPositionMode, false, mFixInterval)) {
mStarted = false;
Log.e(TAG, "native_start failed in startNavigating()");
+ return;
}
// reset SV count to zero
updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
mFixCount = 0;
mFixRequestTime = System.currentTimeMillis();
+ // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
+ // and our fix interval is not short
+ if (mFixInterval >= NO_FIX_TIMEOUT) {
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent);
+ }
}
}
@@ -695,6 +713,17 @@
}
}
+ private void hibernate() {
+ // stop GPS until our next fix interval arrives
+ stopNavigating();
+ mFixCount = 0;
+ mAlarmManager.cancel(mTimeoutIntent);
+ mAlarmManager.cancel(mWakeupIntent);
+ long now = SystemClock.elapsedRealtime();
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent);
+ }
+
/**
* called from native code to update our position.
*/
@@ -762,6 +791,7 @@
}
if (mStarted && mStatus != LocationProvider.AVAILABLE) {
+ mAlarmManager.cancel(mTimeoutIntent);
// send an intent to notify that the GPS is receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, true);
@@ -771,12 +801,7 @@
if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) {
if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT");
- stopNavigating();
- mFixCount = 0;
- mAlarmManager.cancel(mWakeupIntent);
- long now = SystemClock.elapsedRealtime();
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent);
+ hibernate();
}
}
@@ -881,7 +906,7 @@
updateStatus(mStatus, svCount);
if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
- System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
+ System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) {
// send an intent to notify that the GPS is no longer receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, false);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e43c9c4..cfdf5e3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -39,11 +39,6 @@
private final Context mContext;
private final Handler mHandler;
- // used to listen for updates to the sound effects settings so we don't
- // poll it for every UI sound
- private ContentObserver mContentObserver;
-
-
private static String TAG = "AudioManager";
private static boolean DEBUG = false;
private static boolean localLOGV = DEBUG || android.util.Config.LOGV;
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index f05842d..8be11df 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -31,7 +31,7 @@
*/
public class MediaFile {
// comma separated list of all file extensions supported by the media scanner
- public static String sFileExtensions;
+ public final static String sFileExtensions;
// Audio file types
public static final int FILE_TYPE_MP3 = 1;
@@ -93,7 +93,7 @@
= new HashMap<String, Integer>();
static void addFileType(String extension, int fileType, String mimeType) {
sFileTypeMap.put(extension, new MediaFileType(fileType, mimeType));
- sMimeTypeMap.put(mimeType, new Integer(fileType));
+ sMimeTypeMap.put(mimeType, Integer.valueOf(fileType));
}
static {
addFileType("MP3", FILE_TYPE_MP3, "audio/mpeg");
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index b13c2e6..3803d9d 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -149,7 +149,9 @@
fd.close();
}
}
- } catch (java.io.IOException e) {}
+ } catch (java.io.IOException e) {
+ Log.d(TAG, "error loading " + path);
+ }
return id;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index 760b6b5..407b4b36 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -23,7 +23,8 @@
*
*/
public class MediaNames {
-
+ //A directory to hold all kinds of media files
+ public static final String MEDIA_SAMPLE_POOL = "/sdcard/media_api/samples/";
//Audio files
public static final String MP3CBR = "/sdcard/media_api/music/MP3CBR.mp3";
public static final String MP3VBR = "/sdcard/media_api/music/MP3VBR.mp3";
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 d9e17ea..cbd44ab 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -34,6 +34,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.Random;
/**
* Junit / Instrumentation test case for the media player api
@@ -50,8 +51,9 @@
private static final Object lock = new Object();
private static final Object prepareDone = new Object();
private static final Object videoSizeChanged = new Object();
+ private static final Object onCompletion = new Object();
private static boolean onPrepareSuccess = false;
-
+ private static boolean onCompleteSuccess = false;
public static String printCpuInfo(){
String cm = "dumpsys cpuinfo";
@@ -725,8 +727,75 @@
}
return onPrepareSuccess;
}
-
-
-
-}
+ static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
+ public void onCompletion(MediaPlayer mp) {
+ synchronized (onCompletion) {
+ Log.v(TAG, "notify the completion callback");
+ onCompletion.notify();
+ onCompleteSuccess = true;
+ }
+ }
+ };
+
+ // For each media file, forward twice and backward once, then play to the end
+ public static boolean playMediaSamples(String filePath) throws Exception {
+ int duration = 0;
+ int curPosition = 0;
+ int nextPosition = 0;
+ int waittime = 0;
+ Random r = new Random();
+ initializeMessageLooper();
+ synchronized (lock) {
+ try {
+ lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
+ } catch(Exception e) {
+ Log.v(TAG, "looper was interrupted.");
+ return false;
+ }
+ }
+ try {
+ mMediaPlayer.setOnCompletionListener(mCompletionListener);
+ Log.v(TAG, "playMediaSamples: sample file name " + filePath);
+ mMediaPlayer.setDataSource(filePath);
+ mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
+ mMediaPlayer.prepare();
+ duration = mMediaPlayer.getDuration();
+ Log.v(TAG, "playMediaSamples: duration = " + duration);
+ // start to play
+ mMediaPlayer.start();
+ // randomly play for time within (0, duration/3)
+ Thread.sleep(r.nextInt(duration/3));
+ mMediaPlayer.pause();
+ Log.v(TAG, "playMediaSamples: current position after pause: "
+ + mMediaPlayer.getCurrentPosition());
+ // seek to position (0, 2/3*duration)
+ nextPosition = mMediaPlayer.getCurrentPosition() + r.nextInt(duration/3);
+ mMediaPlayer.seekTo(nextPosition);
+ Log.v(TAG, "playMediaSamples: current position after the first seek:"
+ + mMediaPlayer.getCurrentPosition());
+ // play for another short time
+ mMediaPlayer.start();
+ Thread.sleep(r.nextInt(duration/6));
+ Log.v(TAG, "playMediaSamples: position after the second play:"
+ + mMediaPlayer.getCurrentPosition());
+ // seek to a random position (0, duration)
+ mMediaPlayer.seekTo(r.nextInt(duration));
+ Log.v(TAG, "playMediaSamples: current position after the second seek:"
+ + mMediaPlayer.getCurrentPosition());
+ waittime = duration - mMediaPlayer.getCurrentPosition();
+ synchronized(onCompletion){
+ try {
+ onCompletion.wait(waittime + 30000);
+ }catch (Exception e) {
+ Log.v(TAG, "playMediaSamples are interrupted");
+ return false;
+ }
+ }
+ terminateMessageLooper();
+ }catch (Exception e) {
+ Log.v(TAG, "playMediaSamples:" + e.getMessage());
+ }
+ return onCompleteSuccess;
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index 8be7058..94c69a8 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -26,6 +26,8 @@
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
+import java.io.File;
+
/**
* Junit / Instrumentation test case for the media player api
@@ -456,4 +458,29 @@
CodecTest.prepareAsyncCallback(MediaNames.STREAM_H264_480_360_1411k, true);
assertTrue("StreamH264PrepareAsyncCallback", onPrepareSuccess);
}
+
+ //Provide a tool to play all kinds of media files in a directory
+ @Suppress
+ @LargeTest
+ public void testMediaSamples() throws Exception {
+ // load directory files
+ boolean onCompleteSuccess = false;
+ File dir = new File(MediaNames.MEDIA_SAMPLE_POOL);
+ String[] children = dir.list();
+ if (children == null) {
+ Log.v("MediaPlayerApiTest:testMediaSamples", "dir is empty");
+ return;
+ } else {
+ for (int i = 0; i < children.length; i++) {
+ //Get filename of directory
+ String filename = children[i];
+ Log.v("MediaPlayerApiTest",
+ "testMediaSamples: file to be played: "
+ + dir + "/" + filename);
+ onCompleteSuccess =
+ CodecTest.playMediaSamples(dir + "/" + filename);
+ assertTrue("testMediaSamples", onCompleteSuccess);
+ }
+ }
+ }
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 5ba6b76..23304d5 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -39,7 +39,7 @@
GLES_CM/gl.cpp.arm \
#
-LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL
+LOCAL_SHARED_LIBRARIES += libcutils libEGL
LOCAL_LDLIBS := -lpthread -ldl
LOCAL_MODULE:= libGLESv1_CM
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index b0997b1..7340357 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -890,16 +890,10 @@
cname +
" = (" +
cfunc.getArgType(cIndex).getDeclaration() +
- ") _env->GetDirectBufferAddress(" +
- (mUseCPlusPlus ? "" : "_env, ") +
+ ") getDirectBufferPointer(_env, " +
cname + "_buf);");
String iii = " ";
- out.println(iii + indent + "if ( ! " + cname + " ) {");
- out.println(iii + iii + indent +
- (mUseCPlusPlus ? "_env" : "(*_env)") +
- "->ThrowNew(" +
- (mUseCPlusPlus ? "" : "_env, ") +
- "IAEClass, \"Must use a native order direct Buffer\");");
+ out.println(iii + indent + "if ( ! " + cname + " ) {");
out.println(iii + iii + indent + "return;");
out.println(iii + indent + "}");
} else {
diff --git a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
index 3948fd3..e1c09f4 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
@@ -132,6 +132,19 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
static int
getNumCompressedTextureFormats() {
int numCompressedTextureFormats = 0;
diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
index 11c6087..4896acb 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
+++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
@@ -132,6 +132,19 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
static int
getNumCompressedTextureFormats() {
int numCompressedTextureFormats = 0;
diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java
new file mode 100644
index 0000000..c205fc0
--- /dev/null
+++ b/services/java/com/android/server/AccessibilityManagerService.java
@@ -0,0 +1,668 @@
+/*
+ ** Copyright 2009, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ ** http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+package com.android.server;
+
+import static android.util.Config.LOGV;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.HandlerCaller.SomeArgs;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceConnection;
+import android.accessibilityservice.IEventListener;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.IAccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This class is instantiated by the system as a system level service and can be
+ * accessed only by the system. The task of this service is to be a centralized
+ * event dispatch for {@link AccessibilityEvent}s generated across all processes
+ * on the device. Events are dispatched to {@link AccessibilityService}s.
+ *
+ * @hide
+ */
+public class AccessibilityManagerService extends IAccessibilityManager.Stub
+ implements HandlerCaller.Callback {
+
+ private static final String LOG_TAG = "AccessibilityManagerService";
+
+ private static int sIdCounter = 0;
+
+ private static final int OWN_PROCESS_ID = android.os.Process.myPid();
+
+ private static final int DO_SET_SERVICE_INFO = 10;
+
+ final HandlerCaller mCaller;
+
+ final Context mContext;
+
+ final Object mLock = new Object();
+
+ final List<Service> mServices = new ArrayList<Service>();
+
+ final List<IAccessibilityManagerClient> mClients =
+ new ArrayList<IAccessibilityManagerClient>();
+
+ final Map<ComponentName, Service> mComponentNameToServiceMap =
+ new HashMap<ComponentName, Service>();
+
+ private final List<ServiceInfo> mInstalledServices = new ArrayList<ServiceInfo>();
+
+ private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
+
+ private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':');
+
+ private PackageManager mPackageManager;
+
+ private int mHandledFeedbackTypes = 0;
+
+ private boolean mIsEnabled;
+
+ /**
+ * Handler for delayed event dispatch.
+ */
+ private Handler mHandler = new Handler() {
+
+ @Override
+ public void handleMessage(Message message) {
+ Service service = (Service) message.obj;
+ int eventType = message.arg1;
+
+ synchronized (mLock) {
+ notifyEventListenerLocked(service, eventType);
+ AccessibilityEvent oldEvent = service.mPendingEvents.get(eventType);
+ service.mPendingEvents.remove(eventType);
+ tryRecycleLocked(oldEvent);
+ }
+ }
+ };
+
+ /**
+ * Creates a new instance.
+ *
+ * @param context A {@link Context} instance.
+ */
+ AccessibilityManagerService(Context context) {
+ mContext = context;
+ mPackageManager = mContext.getPackageManager();
+ mCaller = new HandlerCaller(context, this);
+
+ registerPackageChangeAndBootCompletedBroadcastReceiver();
+ registerSettingsContentObservers();
+
+ synchronized (mLock) {
+ populateAccessibilityServiceListLocked();
+ }
+ }
+
+ /**
+ * Registers a {@link BroadcastReceiver} for the events of
+ * adding/changing/removing/restarting a package and boot completion.
+ */
+ private void registerPackageChangeAndBootCompletedBroadcastReceiver() {
+ Context context = mContext;
+
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (mLock) {
+ populateAccessibilityServiceListLocked();
+ manageServicesLocked();
+
+ if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
+ mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+ updateClientsLocked();
+ }
+ }
+ }
+ };
+
+ // package changes
+ IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ packageFilter.addDataScheme("package");
+ context.registerReceiver(broadcastReceiver, packageFilter);
+
+ // boot completed
+ IntentFilter bootFiler = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
+ mContext.registerReceiver(broadcastReceiver, bootFiler);
+ }
+
+ /**
+ * {@link ContentObserver}s for {@link Settings.Secure#ACCESSIBILITY_ENABLED}
+ * and {@link Settings.Secure#ENABLED_ACCESSIBILITY_SERVICES} settings.
+ */
+ private void registerSettingsContentObservers() {
+ ContentResolver contentResolver = mContext.getContentResolver();
+
+ Uri enabledUri = Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_ENABLED);
+ contentResolver.registerContentObserver(enabledUri, false,
+ new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+
+ mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+
+ synchronized (mLock) {
+ if (mIsEnabled) {
+ manageServicesLocked();
+ } else {
+ unbindAllServicesLocked();
+ }
+ updateClientsLocked();
+ }
+ }
+ });
+
+ Uri providersUri =
+ Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ contentResolver.registerContentObserver(providersUri, false,
+ new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+
+ synchronized (mLock) {
+ manageServicesLocked();
+ }
+ }
+ });
+ }
+
+ public void addClient(IAccessibilityManagerClient client) {
+ synchronized (mLock) {
+ try {
+ client.setEnabled(mIsEnabled);
+ mClients.add(client);
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Dead AccessibilityManagerClient: " + client, re);
+ }
+ }
+ }
+
+ public boolean sendAccessibilityEvent(AccessibilityEvent event) {
+ synchronized (mLock) {
+ notifyAccessibilityServicesDelayedLocked(event, false);
+ notifyAccessibilityServicesDelayedLocked(event, true);
+ }
+ // event not scheduled for dispatch => recycle
+ if (mHandledFeedbackTypes == 0) {
+ event.recycle();
+ } else {
+ mHandledFeedbackTypes = 0;
+ }
+
+ return (OWN_PROCESS_ID != Binder.getCallingPid());
+ }
+
+ public List<ServiceInfo> getAccessibilityServiceList() {
+ synchronized (mLock) {
+ return mInstalledServices;
+ }
+ }
+
+ public void interrupt() {
+ synchronized (mLock) {
+ for (int i = 0, count = mServices.size(); i < count; i++) {
+ Service service = mServices.get(i);
+ try {
+ service.mServiceInterface.onInterrupt();
+ } catch (RemoteException re) {
+ if (re instanceof DeadObjectException) {
+ Log.w(LOG_TAG, "Dead " + service.mService + ". Cleaning up.");
+ if (removeDeadServiceLocked(service)) {
+ count--;
+ i--;
+ }
+ } else {
+ Log.e(LOG_TAG, "Error during sending interrupt request to "
+ + service.mService, re);
+ }
+ }
+ }
+ }
+ }
+
+ public void executeMessage(Message message) {
+ switch (message.what) {
+ case DO_SET_SERVICE_INFO:
+ SomeArgs arguments = ((SomeArgs) message.obj);
+
+ AccessibilityServiceInfo info = (AccessibilityServiceInfo) arguments.arg1;
+ Service service = (Service) arguments.arg2;
+
+ synchronized (mLock) {
+ service.mEventTypes = info.eventTypes;
+ service.mFeedbackType = info.feedbackType;
+ String[] packageNames = info.packageNames;
+ if (packageNames != null) {
+ service.mPackageNames.addAll(Arrays.asList(packageNames));
+ }
+ service.mNotificationTimeout = info.notificationTimeout;
+ service.mIsDefault = (info.flags & AccessibilityServiceInfo.DEFAULT) != 0;
+ }
+ return;
+ default:
+ Log.w(LOG_TAG, "Unknown message type: " + message.what);
+ }
+ }
+
+ /**
+ * Populates the cached list of installed {@link AccessibilityService}s.
+ */
+ private void populateAccessibilityServiceListLocked() {
+ mInstalledServices.clear();
+
+ List<ResolveInfo> installedServices = mPackageManager.queryIntentServices(
+ new Intent(AccessibilityService.SERVICE_INTERFACE), PackageManager.GET_SERVICES);
+
+ for (int i = 0, count = installedServices.size(); i < count; i++) {
+ mInstalledServices.add(installedServices.get(i).serviceInfo);
+ }
+ }
+
+ /**
+ * Performs {@link AccessibilityService}s delayed notification. The delay is configurable
+ * and denotes the period after the last event before notifying the service.
+ *
+ * @param event The event.
+ * @param isDefault True to notify default listeners, not default services.
+ */
+ private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event,
+ boolean isDefault) {
+ for (int i = 0, count = mServices.size(); i < count; i++) {
+ Service service = mServices.get(i);
+
+ if (service.mIsDefault == isDefault) {
+ if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) {
+ mHandledFeedbackTypes |= service.mFeedbackType;
+ notifyAccessibilityServiceDelayedLocked(service, event);
+ }
+ }
+ }
+ }
+
+ /**
+ * Performs an {@link AccessibilityService} delayed notification. The delay is configurable
+ * and denotes the period after the last event before notifying the service.
+ *
+ * @param service The service.
+ * @param event The event.
+ */
+ private void notifyAccessibilityServiceDelayedLocked(Service service,
+ AccessibilityEvent event) {
+ synchronized (mLock) {
+ int eventType = event.getEventType();
+ AccessibilityEvent oldEvent = service.mPendingEvents.get(eventType);
+ service.mPendingEvents.put(eventType, event);
+
+ int what = eventType | (service.mId << 16);
+ if (oldEvent != null) {
+ mHandler.removeMessages(what);
+ tryRecycleLocked(oldEvent);
+ }
+
+ Message message = mHandler.obtainMessage(what, service);
+ message.arg1 = event.getEventType();
+ mHandler.sendMessageDelayed(message, service.mNotificationTimeout);
+ }
+ }
+
+ /**
+ * Recycles an event if it can be safely recycled. The condition is that no
+ * not notified service is interested in the event.
+ *
+ * @param event The event.
+ */
+ private void tryRecycleLocked(AccessibilityEvent event) {
+ int eventType = event.getEventType();
+ List<Service> services = mServices;
+
+ // linear in the number of service which is not large
+ for (int i = 0, count = services.size(); i < count; i++) {
+ Service service = services.get(i);
+ if (service.mPendingEvents.get(eventType) == event) {
+ return;
+ }
+ }
+
+ event.recycle();
+ }
+
+ /**
+ * Notifies a service for a scheduled event given the event type.
+ *
+ * @param service The service.
+ * @param eventType The type of the event to dispatch.
+ */
+ private void notifyEventListenerLocked(Service service, int eventType) {
+ IEventListener listener = service.mServiceInterface;
+ AccessibilityEvent event = service.mPendingEvents.get(eventType);
+
+ try {
+ listener.onAccessibilityEvent(event);
+ if (LOGV) {
+ Log.i(LOG_TAG, "Event " + event + " sent to " + listener);
+ }
+ } catch (RemoteException re) {
+ if (re instanceof DeadObjectException) {
+ Log.w(LOG_TAG, "Dead " + service.mService + ". Cleaning up.");
+ synchronized (mLock) {
+ removeDeadServiceLocked(service);
+ }
+ } else {
+ Log.e(LOG_TAG, "Error during sending " + event + " to " + service.mService, re);
+ }
+ }
+ }
+
+ /**
+ * Removes a dead service.
+ *
+ * @param service The service.
+ * @return True if the service was removed, false otherwise.
+ */
+ private boolean removeDeadServiceLocked(Service service) {
+ mServices.remove(service);
+ mHandler.removeMessages(service.mId);
+
+ if (LOGV) {
+ Log.i(LOG_TAG, "Dead service " + service.mService + " removed");
+ }
+
+ if (mServices.isEmpty()) {
+ mIsEnabled = false;
+ updateClientsLocked();
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if given event can be dispatched to a service based on the package of the
+ * event source and already notified services for that event type. Specifically, a
+ * service is notified if it is interested in events from the package and no other service
+ * providing the same feedback type has been notified. Exception are services the
+ * provide generic feedback (feedback type left as a safety net for unforeseen feedback
+ * types) which are always notified.
+ *
+ * @param service The potential receiver.
+ * @param event The event.
+ * @param handledFeedbackTypes The feedback types for which services have been notified.
+ * @return True if the listener should be notified, false otherwise.
+ */
+ private boolean canDispathEventLocked(Service service, AccessibilityEvent event,
+ int handledFeedbackTypes) {
+
+ if (!service.isConfigured()) {
+ return false;
+ }
+
+ if (!service.mService.isBinderAlive()) {
+ removeDeadServiceLocked(service);
+ return false;
+ }
+
+ int eventType = event.getEventType();
+ if ((service.mEventTypes & eventType) != eventType) {
+ return false;
+ }
+
+ Set<String> packageNames = service.mPackageNames;
+ CharSequence packageName = event.getPackageName();
+
+ if (packageNames.isEmpty() || packageNames.contains(packageName)) {
+ int feedbackType = service.mFeedbackType;
+ if ((handledFeedbackTypes & feedbackType) != feedbackType
+ || feedbackType == AccessibilityServiceInfo.FEEDBACK_GENERIC) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Manages services by starting enabled ones and stopping disabled ones.
+ */
+ private void manageServicesLocked() {
+ populateEnabledServicesLocked(mEnabledServices);
+ updateServicesStateLocked(mInstalledServices, mEnabledServices);
+ }
+
+ /**
+ * Unbinds all bound services.
+ */
+ private void unbindAllServicesLocked() {
+ List<Service> services = mServices;
+
+ for (int i = 0, count = services.size(); i < count; i++) {
+ Service service = services.get(i);
+
+ service.unbind();
+ mComponentNameToServiceMap.remove(service.mComponentName);
+ }
+ services.clear();
+ }
+
+ /**
+ * Populates a list with the {@link ComponentName}s of all enabled
+ * {@link AccessibilityService}s.
+ *
+ * @param enabledServices The list.
+ */
+ private void populateEnabledServicesLocked(Set<ComponentName> enabledServices) {
+ enabledServices.clear();
+
+ String servicesValue = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+
+ if (servicesValue != null) {
+ TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+ splitter.setString(servicesValue);
+ while (splitter.hasNext()) {
+ ComponentName enabledService = ComponentName.unflattenFromString(splitter.next());
+ enabledServices.add(enabledService);
+ }
+ }
+ }
+
+ /**
+ * Updates the state of each service by starting (or keeping running) enabled ones and
+ * stopping the rest.
+ *
+ * @param installedServices All installed {@link AccessibilityService}s.
+ * @param enabledServices The {@link ComponentName}s of the enabled services.
+ */
+ private void updateServicesStateLocked(List<ServiceInfo> installedServices,
+ Set<ComponentName> enabledServices) {
+
+ Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap;
+ List<Service> services = mServices;
+
+ for (int i = 0, count = installedServices.size(); i < count; i++) {
+ ServiceInfo intalledService = installedServices.get(i);
+ ComponentName componentName = new ComponentName(intalledService.packageName,
+ intalledService.name);
+ Service service = componentNameToServiceMap.get(componentName);
+
+ if (enabledServices.contains(componentName)) {
+ if (service == null) {
+ new Service(componentName).bind();
+ }
+ } else {
+ if (service != null) {
+ service.unbind();
+ componentNameToServiceMap.remove(componentName);
+ services.remove(service);
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates the state of {@link android.view.accessibility.AccessibilityManager} clients.
+ */
+ private void updateClientsLocked() {
+ for (int i = 0, count = mClients.size(); i < count; i++) {
+ try {
+ mClients.get(i).setEnabled(mIsEnabled);
+ } catch (RemoteException re) {
+ mClients.remove(i);
+ count--;
+ }
+ }
+ }
+
+ /**
+ * This class represents an accessibility service. It stores all per service
+ * data required for the service management, provides API for starting/stopping the
+ * service and is responsible for adding/removing the service in the data structures
+ * for service management. The class also exposes configuration interface that is
+ * passed to the service it represents as soon it is bound. It also serves as the
+ * connection for the service.
+ */
+ class Service extends IAccessibilityServiceConnection.Stub implements ServiceConnection {
+ int mId = 0;
+
+ IBinder mService;
+
+ IEventListener mServiceInterface;
+
+ int mEventTypes;
+
+ int mFeedbackType;
+
+ Set<String> mPackageNames = new HashSet<String>();
+
+ boolean mIsDefault;
+
+ long mNotificationTimeout;
+
+ boolean mIsActive;
+
+ ComponentName mComponentName;
+
+ Intent mIntent;
+
+ // the events pending events to be dispatched to this service
+ final SparseArray<AccessibilityEvent> mPendingEvents =
+ new SparseArray<AccessibilityEvent>();
+
+ Service(ComponentName componentName) {
+ mId = sIdCounter++;
+ mComponentName = componentName;
+ mIntent = new Intent().setComponent(mComponentName);
+ }
+
+ /**
+ * Binds to the accessibility service.
+ */
+ public void bind() {
+ if (mService == null) {
+ mContext.bindService(mIntent, this, Context.BIND_AUTO_CREATE);
+ }
+ }
+
+ /**
+ * Unbinds form the accessibility service and removes it from the data
+ * structures for service management.
+ */
+ public void unbind() {
+ if (mService != null) {
+ mContext.unbindService(this);
+ }
+ }
+
+ /**
+ * Returns if the service is configured i.e. at least event types of interest
+ * and feedback type must be set.
+ *
+ * @return True if the service is configured, false otherwise.
+ */
+ public boolean isConfigured() {
+ return (mEventTypes != 0 && mFeedbackType != 0);
+ }
+
+ public void setServiceInfo(AccessibilityServiceInfo info) {
+ mCaller.obtainMessageOO(DO_SET_SERVICE_INFO, info, this).sendToTarget();
+ }
+
+ public void onServiceConnected(ComponentName componentName, IBinder service) {
+ mService = service;
+ mServiceInterface = IEventListener.Stub.asInterface(service);
+
+ try {
+ mServiceInterface.setConnection(this);
+ synchronized (mLock) {
+ if (!mServices.contains(this)) {
+ mServices.add(this);
+ mComponentNameToServiceMap.put(componentName, this);
+ }
+ }
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Error while setting Controller for service: " + service, re);
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName componentName) {
+ synchronized (mLock) {
+ Service service = mComponentNameToServiceMap.remove(componentName);
+ mServices.remove(service);
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index db1deae..983329b 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -220,6 +220,9 @@
BackupRequest request;
synchronized (mQueueLock) {
+ if (mBackupQueue == null) {
+ Log.d(TAG, "mBackupQueue is null. WHY?");
+ }
request = mBackupQueue.get(0);
}
diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java
index 72efca5..d8c8c90 100644
--- a/services/java/com/android/server/IntentResolver.java
+++ b/services/java/com/android/server/IntentResolver.java
@@ -163,8 +163,24 @@
return Collections.unmodifiableSet(mFilters);
}
- public List<R> queryIntent(ContentResolver resolver, Intent intent,
- String resolvedType, boolean defaultOnly) {
+ public List<R> queryIntentFromList(Intent intent, String resolvedType,
+ boolean defaultOnly, ArrayList<ArrayList<F>> listCut) {
+ ArrayList<R> resultList = new ArrayList<R>();
+
+ final boolean debug = localLOGV ||
+ ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
+
+ final String scheme = intent.getScheme();
+ int N = listCut.size();
+ for (int i = 0; i < N; ++i) {
+ buildResolveList(intent, debug, defaultOnly,
+ resolvedType, scheme, listCut.get(i), resultList);
+ }
+ sortResults(resultList);
+ return resultList;
+ }
+
+ public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 6ed8b4c..4a2808b 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -16,6 +16,10 @@
package com.android.server;
+import com.android.server.status.IconData;
+import com.android.server.status.NotificationData;
+import com.android.server.status.StatusBarService;
+
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.INotificationManager;
@@ -30,33 +34,29 @@
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
-import android.media.AudioManager;
import android.media.AsyncPlayer;
-import android.media.RingtoneManager;
+import android.media.AudioManager;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Binder;
-import android.os.RemoteException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Power;
+import android.os.RemoteException;
import android.os.Vibrator;
import android.provider.Settings;
-import android.util.Config;
+import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
-import com.android.server.status.IconData;
-import com.android.server.status.NotificationData;
-import com.android.server.status.StatusBarService;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.io.IOException;
class NotificationManagerService extends INotificationManager.Stub
{
@@ -98,7 +98,7 @@
private boolean mBatteryLow;
private boolean mBatteryFull;
private NotificationRecord mLedNotification;
-
+
private static final int BATTERY_LOW_ARGB = 0xFFFF0000; // Charging Low - red solid on
private static final int BATTERY_MEDIUM_ARGB = 0xFFFFFF00; // Charging - orange solid on
private static final int BATTERY_FULL_ARGB = 0xFF00FF00; // Charging Full - green solid on
@@ -594,6 +594,9 @@
Binder.restoreCallingIdentity(identity);
}
}
+
+ sendAccessibilityEventTypeNotificationChangedDoCheck(notification, pkg);
+
} else {
if (old != null && old.statusBarKey != null) {
long identity = Binder.clearCallingIdentity();
@@ -676,6 +679,26 @@
idOut[0] = id;
}
+ private void sendAccessibilityEventTypeNotificationChangedDoCheck(Notification notification,
+ CharSequence packageName) {
+ AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
+ if (!manager.isEnabled()) {
+ return;
+ }
+
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+ event.setPackageName(packageName);
+ event.setClassName(Notification.class.getName());
+ event.setParcelableData(notification);
+ CharSequence tickerText = notification.tickerText;
+ if (!TextUtils.isEmpty(tickerText)) {
+ event.getText().add(tickerText);
+ }
+
+ manager.sendAccessibilityEvent(event);
+ }
+
private void cancelNotificationLocked(NotificationRecord r) {
// status bar
if (r.notification.icon != 0) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4ee0c91..a3c702f 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1203,6 +1203,33 @@
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags) {
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags);
+ return chooseBestActivity(intent, resolvedType, flags, query);
+ }
+
+ public ResolveInfo resolveIntentForPackage(Intent intent, String resolvedType,
+ int flags, String packageName) {
+ ComponentName comp = intent.getComponent();
+ if (comp != null) {
+ // if this is an explicit intent, it must have the same the packageName
+ if (packageName.equals(comp.getPackageName())) {
+ return resolveIntent(intent, resolvedType, flags);
+ }
+ return null;
+ } else {
+ List<ResolveInfo> query = null;
+ synchronized (mPackages) {
+ PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg != null) {
+ query = (List<ResolveInfo>) mActivities.
+ queryIntentForPackage(intent, resolvedType, flags, pkg.activities);
+ }
+ }
+ return chooseBestActivity(intent, resolvedType, flags, query);
+ }
+ }
+
+ private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
+ int flags, List<ResolveInfo> query) {
if (query != null) {
final int N = query.size();
if (N == 1) {
@@ -1243,8 +1270,7 @@
synchronized (mPackages) {
if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
List<PreferredActivity> prefs =
- mSettings.mPreferredActivities.queryIntent(null,
- intent, resolvedType,
+ mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
if (prefs != null && prefs.size() > 0) {
// First figure out how good the original match set is.
@@ -1321,7 +1347,7 @@
synchronized (mPackages) {
return (List<ResolveInfo>)mActivities.
- queryIntent(null, intent, resolvedType, flags);
+ queryIntent(intent, resolvedType, flags);
}
}
@@ -1490,7 +1516,7 @@
String resolvedType, int flags) {
synchronized (mPackages) {
return (List<ResolveInfo>)mReceivers.
- queryIntent(null, intent, resolvedType, flags);
+ queryIntent(intent, resolvedType, flags);
}
}
@@ -1523,8 +1549,7 @@
}
synchronized (mPackages) {
- return (List<ResolveInfo>)mServices.
- queryIntent(null, intent, resolvedType, flags);
+ return (List<ResolveInfo>)mServices.queryIntent(intent, resolvedType, flags);
}
}
@@ -2801,6 +2826,21 @@
// we can't add any new permissions to it.
if (!gp.loadedPermissions.contains(perm)) {
allowed = false;
+ // Except... if this is a permission that was added
+ // to the platform (note: need to only do this when
+ // updating the platform).
+ final int NP = PackageParser.NEW_PERMISSIONS.length;
+ for (int ip=0; ip<NP; ip++) {
+ final PackageParser.NewPermissionInfo npi
+ = PackageParser.NEW_PERMISSIONS[ip];
+ if (npi.name.equals(perm)
+ && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
+ allowed = true;
+ Log.i(TAG, "Auto-granting WRITE_SDCARD to old pkg "
+ + pkg.packageName);
+ break;
+ }
+ }
}
}
if (allowed) {
@@ -2839,20 +2879,33 @@
private final class ActivityIntentResolver
extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
- public List queryIntent(ContentResolver resolver, Intent intent,
- String resolvedType, boolean defaultOnly) {
+ public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(resolver, intent, resolvedType, defaultOnly);
+ return super.queryIntent(intent, resolvedType, defaultOnly);
}
- public List queryIntent(ContentResolver resolver, Intent intent,
- String resolvedType, int flags) {
+ public List queryIntent(Intent intent, String resolvedType, int flags) {
mFlags = flags;
- return super.queryIntent(
- resolver, intent, resolvedType,
+ return super.queryIntent(intent, resolvedType,
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
}
+ public List queryIntentForPackage(Intent intent, String resolvedType, int flags,
+ ArrayList<PackageParser.Activity> packageActivities) {
+ if (packageActivities == null) {
+ return null;
+ }
+ mFlags = flags;
+ final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
+ int N = packageActivities.size();
+ ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut =
+ new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N);
+ for (int i = 0; i < N; ++i) {
+ listCut.add(packageActivities.get(i).intents);
+ }
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
+ }
+
public final void addActivity(PackageParser.Activity a, String type) {
mActivities.put(a.component, a);
if (SHOW_INFO || Config.LOGV) Log.v(
@@ -2860,8 +2913,7 @@
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
int NI = a.intents.size();
- int j;
- for (j=0; j<NI; j++) {
+ for (int j=0; j<NI; j++) {
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
if (SHOW_INFO || Config.LOGV) {
Log.v(TAG, " IntentFilter:");
@@ -2881,8 +2933,7 @@
(a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name);
int NI = a.intents.size();
- int j;
- for (j=0; j<NI; j++) {
+ for (int j=0; j<NI; j++) {
PackageParser.ActivityIntentInfo intent = a.intents.get(j);
if (SHOW_INFO || Config.LOGV) {
Log.v(TAG, " IntentFilter:");
@@ -2969,17 +3020,14 @@
private final class ServiceIntentResolver
extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
- public List queryIntent(ContentResolver resolver, Intent intent,
- String resolvedType, boolean defaultOnly) {
+ public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(resolver, intent, resolvedType, defaultOnly);
+ return super.queryIntent(intent, resolvedType, defaultOnly);
}
- public List queryIntent(ContentResolver resolver, Intent intent,
- String resolvedType, int flags) {
+ public List queryIntent(Intent intent, String resolvedType, int flags) {
mFlags = flags;
- return super.queryIntent(
- resolver, intent, resolvedType,
+ return super.queryIntent(intent, resolvedType,
(flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
}
@@ -3545,7 +3593,9 @@
} else {
// Re installation failed. Restore old information
// Remove new pkg information
- removePackageLI(newPackage, true);
+ if (newPackage != null) {
+ removePackageLI(newPackage, true);
+ }
// Add back the old system package
scanPackageLI(oldPkgSetting.codePath, oldPkgSetting.codePath,
oldPkgSetting.resourcePath,
@@ -5644,6 +5694,7 @@
}
p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
+ p.sharedUser = sharedUser;
if (sharedUser != null) {
p.userId = sharedUser.userId;
} else if (MULTIPLE_APPLICATION_UIDS) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8b7260b..f6c1525 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -228,6 +228,14 @@
}
try {
+ Log.i(TAG, "Starting Accessibility Manager.");
+ ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
+ new AccessibilityManagerService(context));
+ } catch (Throwable e) {
+ Log.e(TAG, "Failure starting Accessibility Manager", e);
+ }
+
+ try {
Log.i(TAG, "Starting Notification Manager.");
ServiceManager.addService(Context.NOTIFICATION_SERVICE,
new NotificationManagerService(context, statusBar, hardware));
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 8850c31..90ab270 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -96,6 +96,11 @@
private int mScanLocksAcquired;
private int mScanLocksReleased;
+ private final List<WifiMulticaster> mMulticasters =
+ new ArrayList<WifiMulticaster>();
+ private int mMulticastEnabled;
+ private int mMulticastDisabled;
+
private final IBatteryStats mBatteryStats;
/**
@@ -1444,10 +1449,12 @@
Settings.System.getInt(mContext.getContentResolver(),
Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0);
if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ Log.d(TAG, "ACTION_SCREEN_ON");
mAlarmManager.cancel(mIdleIntent);
mDeviceIdle = false;
mScreenOff = false;
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ Log.d(TAG, "ACTION_SCREEN_OFF");
mScreenOff = true;
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
@@ -1456,12 +1463,20 @@
* or plugged in to AC).
*/
if (!shouldWifiStayAwake(stayAwakeConditions, mPluggedType)) {
- long triggerTime = System.currentTimeMillis() + idleMillis;
- mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
+ if (!mWifiStateTracker.hasIpAddress()) {
+ // do not keep Wifi awake when screen is off if Wifi is not fully active
+ mDeviceIdle = true;
+ updateWifiState();
+ } else {
+ long triggerTime = System.currentTimeMillis() + idleMillis;
+ Log.d(TAG, "setting ACTION_DEVICE_IDLE timer for " + idleMillis + "ms");
+ mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
+ }
}
/* we can return now -- there's nothing to do until we get the idle intent back */
return;
} else if (action.equals(ACTION_DEVICE_IDLE)) {
+ Log.d(TAG, "got ACTION_DEVICE_IDLE");
mDeviceIdle = true;
} else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
/*
@@ -1472,9 +1487,11 @@
* the already-set timer.
*/
int pluggedType = intent.getIntExtra("plugged", 0);
+ Log.d(TAG, "ACTION_BATTERY_CHANGED pluggedType: " + pluggedType);
if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
!shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
long triggerTime = System.currentTimeMillis() + idleMillis;
+ Log.d(TAG, "setting ACTION_DEVICE_IDLE timer for " + idleMillis + "ms");
mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
mPluggedType = pluggedType;
return;
@@ -1727,21 +1744,9 @@
}
}
- private class WifiLock implements IBinder.DeathRecipient {
- String mTag;
- int mLockMode;
- IBinder mBinder;
-
+ private class WifiLock extends WifiDeathRecipient {
WifiLock(int lockMode, String tag, IBinder binder) {
- super();
- mTag = tag;
- mLockMode = lockMode;
- mBinder = binder;
- try {
- mBinder.linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
+ super(lockMode, tag, binder);
}
public void binderDied() {
@@ -1751,7 +1756,7 @@
}
public String toString() {
- return "WifiLock{" + mTag + " type=" + mLockMode + " binder=" + mBinder + "}";
+ return "WifiLock{" + mTag + " type=" + mMode + " binder=" + mBinder + "}";
}
}
@@ -1771,7 +1776,7 @@
return WifiManager.WIFI_MODE_FULL;
}
for (WifiLock l : mList) {
- if (l.mLockMode == WifiManager.WIFI_MODE_FULL) {
+ if (l.mMode == WifiManager.WIFI_MODE_FULL) {
return WifiManager.WIFI_MODE_FULL;
}
}
@@ -1826,7 +1831,7 @@
int uid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- switch(wifiLock.mLockMode) {
+ switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
++mFullLocksAcquired;
mBatteryStats.noteFullWifiLockAcquired(uid);
@@ -1862,7 +1867,7 @@
int uid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
try {
- switch(wifiLock.mLockMode) {
+ switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL:
++mFullLocksReleased;
mBatteryStats.noteFullWifiLockReleased(uid);
@@ -1881,4 +1886,110 @@
updateWifiState();
return hadLock;
}
+
+ private abstract class WifiDeathRecipient
+ implements IBinder.DeathRecipient {
+ String mTag;
+ int mMode;
+ IBinder mBinder;
+
+ WifiDeathRecipient(int mode, String tag, IBinder binder) {
+ super();
+ mTag = tag;
+ mMode = mode;
+ mBinder = binder;
+ try {
+ mBinder.linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ binderDied();
+ }
+ }
+ }
+
+ private class WifiMulticaster extends WifiDeathRecipient {
+ WifiMulticaster(String tag, IBinder binder) {
+ super(Binder.getCallingUid(), tag, binder);
+ }
+
+ public void binderDied() {
+ Log.e(TAG, "WifiMulticaster binderDied");
+ synchronized (mMulticasters) {
+ int i = mMulticasters.indexOf(this);
+ if (i != -1) {
+ removeMulticasterLocked(i, mMode);
+ }
+ }
+ }
+
+ public String toString() {
+ return "WifiMulticaster{" + mTag + " binder=" + mBinder + "}";
+ }
+
+ public int getUid() {
+ return mMode;
+ }
+ }
+
+ public void enableWifiMulticast(IBinder binder, String tag) {
+ enforceChangePermission();
+
+ synchronized (mMulticasters) {
+ mMulticastEnabled++;
+ mMulticasters.add(new WifiMulticaster(tag, binder));
+ // Note that we could call stopPacketFiltering only when
+ // our new size == 1 (first call), but this function won't
+ // be called often and by making the stopPacket call each
+ // time we're less fragile and self-healing.
+ WifiNative.stopPacketFiltering();
+ }
+
+ int uid = Binder.getCallingUid();
+ Long ident = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteWifiMulticastEnabled(uid);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ public void disableWifiMulticast() {
+ enforceChangePermission();
+
+ int uid = Binder.getCallingUid();
+ synchronized (mMulticasters) {
+ mMulticastDisabled++;
+ int size = mMulticasters.size();
+ for (int i = size - 1; i >= 0; i--) {
+ WifiMulticaster m = mMulticasters.get(i);
+ if ((m != null) && (m.getUid() == uid)) {
+ removeMulticasterLocked(i, uid);
+ }
+ }
+ }
+ }
+
+ private void removeMulticasterLocked(int i, int uid)
+ {
+ mMulticasters.remove(i);
+ if (mMulticasters.size() == 0) {
+ WifiNative.startPacketFiltering();
+ }
+
+ Long ident = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteWifiMulticastDisabled(uid);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ public boolean isWifiMulticastEnabled() {
+ enforceAccessPermission();
+
+ synchronized (mMulticasters) {
+ return (mMulticasters.size() > 0);
+ }
+ }
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3fa5baf..a04d73a 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1300,7 +1300,6 @@
mKeyWaiter.handleNewWindowLocked(mCurrentFocus);
}
}
-
if (localLOGV) Log.v(
TAG, "New client " + client.asBinder()
+ ": window=" + win);
@@ -7732,7 +7731,6 @@
int i;
// FIRST LOOP: Perform a layout, if needed.
-
performLayoutLockedInner();
if (mFxSession == null) {
@@ -7752,7 +7750,6 @@
}
// SECOND LOOP: Execute animations and update visibility of windows.
-
boolean orientationChangeComplete = true;
Session holdScreen = null;
float screenBrightness = -1;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9471eff..c4dbd32 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -10176,8 +10176,6 @@
}
}
- final ContentResolver resolver = mContext.getContentResolver();
-
// Figure out who all will receive this broadcast.
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
@@ -10200,8 +10198,7 @@
ActivityThread.getPackageManager().queryIntentReceivers(
intent, resolvedType, STOCK_PM_FLAGS);
}
- registeredReceivers = mReceiverResolver.queryIntent(resolver,
- intent, resolvedType, false);
+ registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index a21893b..0387be5 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -261,6 +261,20 @@
}
}
+ public void noteWifiMulticastEnabled(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteWifiMulticastEnabledLocked(uid);
+ }
+ }
+
+ public void noteWifiMulticastDisabled(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteWifiMulticastDisabledLocked(uid);
+ }
+ }
+
public boolean isOnBattery() {
return mStats.isOnBattery();
}
diff --git a/services/java/com/android/server/status/IconMerger.java b/services/java/com/android/server/status/IconMerger.java
index 37fdbfb..5b80638 100644
--- a/services/java/com/android/server/status/IconMerger.java
+++ b/services/java/com/android/server/status/IconMerger.java
@@ -8,8 +8,6 @@
public class IconMerger extends LinearLayout {
- private static final boolean SPEW = false;
-
StatusBarService service;
StatusBarIcon moreIcon;
@@ -29,7 +27,7 @@
int fitRight = -1;
for (i=N-1; i>=0; i--) {
final View child = getChildAt(i);
- if (child != null && child.getVisibility() != GONE) {
+ if (child.getVisibility() != GONE) {
fitRight = child.getRight();
break;
}
@@ -45,7 +43,7 @@
moreView = child;
startIndex = i+1;
}
- else if (child != null && child.getVisibility() != GONE) {
+ else if (child.getVisibility() != GONE) {
fitLeft = child.getLeft();
break;
}
@@ -71,7 +69,7 @@
int number = 0;
for (i=startIndex; i<N; i++) {
final View child = getChildAt(i);
- if (child != null && child.getVisibility() != GONE) {
+ if (child.getVisibility() != GONE) {
int childLeft = child.getLeft();
int childRight = child.getRight();
if (childLeft < breakingPoint) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index 88acb1b..3f794a8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -95,16 +95,20 @@
apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
+ private void tearDownData(Message msg) {
+ if (dataLink != null) {
+ dataLink.disconnect();
+ }
+
+ if (phone.mCM.getRadioState().isOn()) {
+ phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
+ }
+ }
+
protected void disconnect(Message msg) {
onDisconnect = msg;
if (state == State.ACTIVE) {
- if (dataLink != null) {
- dataLink.disconnect();
- }
-
- if (phone.mCM.getRadioState().isOn()) {
- phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
- }
+ tearDownData(msg);
} else if (state == State.ACTIVATING) {
receivedDisconnectReq = true;
} else {
@@ -243,7 +247,7 @@
// Don't bother reporting success if there's already a
// pending disconnect request, since DataConnectionTracker
// has already updated its state.
- disconnect(onDisconnect);
+ tearDownData(onDisconnect);
} else {
String[] response = ((String[]) ar.result);
cid = Integer.parseInt(response[0]);
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index bf1629f..73ae3b9 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -57,11 +57,15 @@
}
@Override
- public Intent getLaunchIntentForPackage(String packageName)
- throws NameNotFoundException {
+ public Intent getLaunchIntentForPackage(String packageName) {
throw new UnsupportedOperationException();
}
-
+
+ @Override
+ public ResolveInfo resolveActivity(Intent intent, int flags, String packageName) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public int[] getPackageGids(String packageName) throws NameNotFoundException {
throw new UnsupportedOperationException();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
index d775dc2..8b6cad1 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java
@@ -509,9 +509,13 @@
Cursor c;
mDatabase.execSQL("CREATE TABLE tokens (" +
"token TEXT COLLATE unicode," +
- "source INTEGER " +
+ "source INTEGER," +
+ "token_index INTEGER" +
");");
- String[] cols = new String[]{"token", "source"};
+ mDatabase.execSQL("CREATE TABLE tokens_no_index (" +
+ "token TEXT COLLATE unicode," +
+ "source INTEGER" +
+ ");");
Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
"SELECT _TOKENIZE(NULL, NULL, NULL, NULL)", null));
@@ -523,17 +527,22 @@
"SELECT _TOKENIZE('tokens', 10, 'some string', NULL)", null));
Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase,
- "SELECT _TOKENIZE('tokens', 1, 'some string ok', ' ')", null));
+ "SELECT _TOKENIZE('tokens', 11, 'some string ok', ' ', 1)", null));
+ Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens_no_index', 20, 'some string ok', ' ')", null));
+ Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT _TOKENIZE('tokens_no_index', 21, 'foo bar baz', ' ', 0)", null));
+
// test Chinese
String chinese = new String("\u4eac\u4ec5 \u5c3d\u5f84\u60ca");
Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
- "SELECT _TOKENIZE('tokens', 1,'" + chinese + "', ' ')", null));
+ "SELECT _TOKENIZE('tokens', 12,'" + chinese + "', ' ', 1)", null));
String icustr = new String("Fr\u00e9d\u00e9ric Hj\u00f8nnev\u00e5g");
Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
- "SELECT _TOKENIZE('tokens', 1, '" + icustr + "', ' ')", null));
+ "SELECT _TOKENIZE('tokens', 13, '" + icustr + "', ' ', 1)", null));
Assert.assertEquals(7, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens;", null));
@@ -541,42 +550,102 @@
String key = DatabaseUtils.getHexCollationKey("Frederic Hjonneva");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey("Hjonneva");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey("some string ok");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey("string");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey("ok");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey(chinese);
String[] a = new String[1];
a[0] = key;
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token= ?", a));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token= ?", a));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token= ?", a));
a[0] += "*";
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB ?", a));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB ?", a));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB ?", a));
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token= '" + key + "'", null));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token= '" + key + "'", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token= '" + key + "'", null));
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
key = DatabaseUtils.getHexCollationKey("\u4eac\u4ec5");
Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
+ key = DatabaseUtils.getHexCollationKey("\u5c3d\u5f84\u60ca");
+ Log.d("DatabaseGeneralTest", "key = " + key);
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT token_index from tokens where token GLOB '" + key + "*'", null));
Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase,
"SELECT count(*) from tokens where token GLOB 'ab*'", null));
+
+ key = DatabaseUtils.getHexCollationKey("some string ok");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(20, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null));
+
+ key = DatabaseUtils.getHexCollationKey("bar");
+ Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null));
+ Assert.assertEquals(21, DatabaseUtils.longForQuery(mDatabase,
+ "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null));
}
@MediumTest
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index caef861..f169a26 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -223,7 +223,10 @@
}
private String getExpectedResultFile(String test) {
- String shortName = test.substring(0, test.lastIndexOf('.'));
+ int pos = test.lastIndexOf('.');
+ if(pos == -1)
+ return null;
+ String shortName = test.substring(0, pos);
return shortName + "-expected.txt";
}
@@ -303,6 +306,10 @@
});
String resultFile = getResultFile(test);
+ if(resultFile == null) {
+ //simply ignore this test
+ return;
+ }
if (mRebaselineResults) {
String expectedResultFile = getExpectedResultFile(test);
File f = new File(expectedResultFile);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index 81cf3a8..c792e8e 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -69,11 +69,14 @@
TestShellActivity activity = (TestShellActivity) getActivity();
+ Log.v(LOGTAG, "About to run tests, calling gc first...");
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
// Run tests
runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
- // TODO(fqian): let am instrumentation pass in the command line, currently
- // am instrument does not allow spaces in the command.
dumpMemoryInfo();
// Kill activity
@@ -82,6 +85,11 @@
private void dumpMemoryInfo() {
try {
+ Log.v(LOGTAG, "About to dump meminfo, calling gc first...");
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
Log.v(LOGTAG, "Dumping memory information.");
FileOutputStream out = new FileOutputStream(LOAD_TEST_RESULT, true);
diff --git a/tests/FrameworkTest/AndroidManifest.xml b/tests/FrameworkTest/AndroidManifest.xml
index c70302b..4e4ebffc 100644
--- a/tests/FrameworkTest/AndroidManifest.xml
+++ b/tests/FrameworkTest/AndroidManifest.xml
@@ -20,6 +20,9 @@
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.HARDWARE_TEST" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_VIEW_TYPES" />
+ <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_TRANSITION_TYPES" />
+ <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_NOTIFICATION_TYPES" />
<application android:theme="@style/Theme">
<uses-library android:name="android.test.runner" />
@@ -939,7 +942,7 @@
</intent-filter>
</activity>
- <activity android:name="android.widget.AutoCompleteTextViewSimple"
+ <activity android:name="android.widget.AutoCompleteTextViewSimple"
android:label="AutoCompleteTextViewSimple">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -947,6 +950,12 @@
</intent-filter>
</activity>
+ <service android:name=".accessibility.AccessibilityTestService">
+ <intent-filter>
+ <action android:name="android.accessibilityservice.AccessibilityService" />
+ </intent-filter>
+ </service>
+
</application>
</manifest>
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/accessibility/AccessibilityTestService.java b/tests/FrameworkTest/src/com/android/frameworktest/accessibility/AccessibilityTestService.java
new file mode 100644
index 0000000..83d6056
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/accessibility/AccessibilityTestService.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworktest.accessibility;
+
+import android.accessibilityservice.AccessibilityService;
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Notification;
+import android.util.Log;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * This class text the accessibility framework end to end.
+ * <p>
+ * Note: Since accessibility is provided by {@link AccessibilityService}s we create one,
+ * and it generates an event and an interruption dispatching them through the
+ * {@link AccessibilityManager}. We verify the received result. To trigger the test
+ * go to Settings->Accessibility and select the enable accessibility check and then
+ * select the check for this service (same name as the class).
+ */
+public class AccessibilityTestService extends AccessibilityService {
+
+ private static final String LOG_TAG = "AccessibilityTestService";
+
+ private static final String CLASS_NAME = "foo.bar.baz.Test";
+ private static final String PACKAGE_NAME = "foo.bar.baz";
+ private static final String TEXT = "Some stuff";
+ private static final String BEFORE_TEXT = "Some other stuff";
+
+ private static final String CONTENT_DESCRIPTION = "Content description";
+
+ private static final int ITEM_COUNT = 10;
+ private static final int CURRENT_ITEM_INDEX = 1;
+ private static final int INTERRUPT_INVOCATION_TYPE = 0x00000200;
+
+ private static final int FROM_INDEX = 1;
+ private static final int ADDED_COUNT = 2;
+ private static final int REMOVED_COUNT = 1;
+
+ private static final int NOTIFICATION_TIMEOUT_MILLIS = 80;
+
+ private int mReceivedResult;
+
+ private Timer mTimer = new Timer();
+
+ @Override
+ public void onServiceConnected() {
+ AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+ info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
+ info.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
+ info.notificationTimeout = NOTIFICATION_TIMEOUT_MILLIS;
+ info.flags &= AccessibilityServiceInfo.DEFAULT;
+ setServiceInfo(info);
+
+ // we need to wait until the system picks our configuration
+ // otherwise it will not notify us
+ mTimer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ testAccessibilityEventDispatching();
+ testInterrupt();
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Error in testing Accessibility feature", e);
+ }
+ }
+ }, 1000);
+ }
+
+ /**
+ * Check here if the event we received is actually the one we sent.
+ */
+ @Override
+ public void onAccessibilityEvent(AccessibilityEvent event) {
+ assert(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED == event.getEventType());
+ assert(event != null);
+ assert(event.getEventTime() > 0);
+ assert(CLASS_NAME.equals(event.getClassName()));
+ assert(PACKAGE_NAME.equals(event.getPackageName()));
+ assert(1 == event.getText().size());
+ assert(TEXT.equals(event.getText().get(0)));
+ assert(BEFORE_TEXT.equals(event.getBeforeText()));
+ assert(event.isChecked());
+ assert(CONTENT_DESCRIPTION.equals(event.getContentDescription()));
+ assert(ITEM_COUNT == event.getItemCount());
+ assert(CURRENT_ITEM_INDEX == event.getCurrentItemIndex());
+ assert(event.isEnabled());
+ assert(event.isPassword());
+ assert(FROM_INDEX == event.getFromIndex());
+ assert(ADDED_COUNT == event.getAddedCount());
+ assert(REMOVED_COUNT == event.getRemovedCount());
+ assert(event.getParcelableData() != null);
+ assert(1 == ((Notification) event.getParcelableData()).icon);
+
+ // set the type of the receved request
+ mReceivedResult = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
+ }
+
+ /**
+ * Set a flag that we received the interrupt request.
+ */
+ @Override
+ public void onInterrupt() {
+
+ // set the type of the receved request
+ mReceivedResult = INTERRUPT_INVOCATION_TYPE;
+ }
+
+ /**
+ * If an {@link AccessibilityEvent} is sent and received correctly.
+ */
+ public void testAccessibilityEventDispatching() throws Exception {
+ AccessibilityEvent event =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+
+ assert(event != null);
+ event.setClassName(CLASS_NAME);
+ event.setPackageName(PACKAGE_NAME);
+ event.getText().add(TEXT);
+ event.setBeforeText(BEFORE_TEXT);
+ event.setChecked(true);
+ event.setContentDescription(CONTENT_DESCRIPTION);
+ event.setItemCount(ITEM_COUNT);
+ event.setCurrentItemIndex(CURRENT_ITEM_INDEX);
+ event.setEnabled(true);
+ event.setPassword(true);
+ event.setFromIndex(FROM_INDEX);
+ event.setAddedCount(ADDED_COUNT);
+ event.setRemovedCount(REMOVED_COUNT);
+ event.setParcelableData(new Notification(1, "Foo", 1234));
+
+ AccessibilityManager.getInstance(this).sendAccessibilityEvent(event);
+
+ assert(mReceivedResult == event.getEventType());
+
+ Log.i(LOG_TAG, "AccessibilityTestService#testAccessibilityEventDispatching: Success");
+ }
+
+ /**
+ * If accessibility feedback interruption is triggered and received correctly.
+ */
+ public void testInterrupt() throws Exception {
+ AccessibilityManager.getInstance(this).interrupt();
+
+ assert(INTERRUPT_INVOCATION_TYPE == mReceivedResult);
+
+ Log.i(LOG_TAG, "AccessibilityTestService#testInterrupt: Success");
+ }
+}
+
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/accessibility/RecycleAccessibilityEventTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/accessibility/RecycleAccessibilityEventTest.java
new file mode 100644
index 0000000..d6380f9
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/accessibility/RecycleAccessibilityEventTest.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworktest.accessibility;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.accessibility.AccessibilityEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * This class exercises the caching and recycling of {@link AccessibilityEvent}s.
+ */
+public class RecycleAccessibilityEventTest extends TestCase {
+
+ private static final String CLASS_NAME = "foo.bar.baz.Test";
+ private static final String PACKAGE_NAME = "foo.bar.baz";
+ private static final String TEXT = "Some stuff";
+
+ private static final String CONTENT_DESCRIPTION = "Content description";
+ private static final int ITEM_COUNT = 10;
+ private static final int CURRENT_ITEM_INDEX = 1;
+
+ private static final int FROM_INDEX = 1;
+ private static final int ADDED_COUNT = 2;
+ private static final int REMOVED_COUNT = 1;
+
+ /**
+ * If an {@link AccessibilityEvent} is marshaled/unmarshaled correctly
+ */
+ @MediumTest
+ public void testAccessibilityEventViewTextChangedType() {
+ AccessibilityEvent first =
+ AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
+ assertNotNull(first);
+
+ first.setClassName(CLASS_NAME);
+ first.setPackageName(PACKAGE_NAME);
+ first.getText().add(TEXT);
+ first.setFromIndex(FROM_INDEX);
+ first.setAddedCount(ADDED_COUNT);
+ first.setRemovedCount(REMOVED_COUNT);
+ first.setChecked(true);
+ first.setContentDescription(CONTENT_DESCRIPTION);
+ first.setItemCount(ITEM_COUNT);
+ first.setCurrentItemIndex(CURRENT_ITEM_INDEX);
+ first.setEnabled(true);
+ first.setPassword(true);
+
+ first.recycle();
+
+ assertNotNull(first);
+ assertNull(first.getClassName());
+ assertNull(first.getPackageName());
+ assertEquals(0, first.getText().size());
+ assertFalse(first.isChecked());
+ assertNull(first.getContentDescription());
+ assertEquals(0, first.getItemCount());
+ assertEquals(AccessibilityEvent.INVALID_POSITION, first.getCurrentItemIndex());
+ assertFalse(first.isEnabled());
+ assertFalse(first.isPassword());
+ assertEquals(0, first.getFromIndex());
+ assertEquals(0, first.getAddedCount());
+ assertEquals(0, first.getRemovedCount());
+
+ // get another event from the pool (this must be the recycled first)
+ AccessibilityEvent second = AccessibilityEvent.obtain();
+ assertEquals(first, second);
+ }
+}
diff --git a/tests/backup/backup_helper_test.cpp b/tests/backup/backup_helper_test.cpp
index 6da16b4..1085909 100644
--- a/tests/backup/backup_helper_test.cpp
+++ b/tests/backup/backup_helper_test.cpp
@@ -3,6 +3,8 @@
#include <stdio.h>
#include <string.h>
+using namespace android;
+
#if TEST_BACKUP_HELPERS
// ============================================================
@@ -20,6 +22,8 @@
{ "backup_helper_test_empty", backup_helper_test_empty, 0, false },
{ "backup_helper_test_four", backup_helper_test_four, 0, false },
{ "backup_helper_test_files", backup_helper_test_files, 0, false },
+ { "backup_helper_test_data_writer", backup_helper_test_data_writer, 0, false },
+ { "backup_helper_test_data_reader", backup_helper_test_data_reader, 0, false },
{ 0, NULL, 0, false}
};
diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
index de68cb7..af7dfd4 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
@@ -83,6 +83,27 @@
bm.dataChanged();
}
},
+ new Test("Clear File") {
+ void run() {
+ PrintStream output = null;
+ try {
+ output = new PrintStream(openFileOutput(FILE_NAME, MODE_PRIVATE));
+ output.close();
+ } catch (IOException ex) {
+ if (output != null) {
+ output.close();
+ }
+ }
+ BackupManager bm = new BackupManager(BackupTestActivity.this);
+ bm.dataChanged();
+ }
+ },
+ new Test("Poke") {
+ void run() {
+ BackupManager bm = new BackupManager(BackupTestActivity.this);
+ bm.dataChanged();
+ }
+ },
new Test("Show Shared Pref") {
void run() {
SharedPreferences prefs = getSharedPreferences(PREF_GROUP_SETTINGS, MODE_PRIVATE);
diff --git a/tests/backup/src/com/android/backuptest/BackupTestService.java b/tests/backup/src/com/android/backuptest/BackupTestService.java
index c58c98b..00eb86e 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestService.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestService.java
@@ -17,6 +17,8 @@
package com.android.backuptest;
import android.backup.BackupService;
+import android.backup.BackupDataOutput;
+import android.backup.FileBackupHelper;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -25,10 +27,12 @@
static final String TAG = "BackupTestService";
@Override
- public void onBackup(ParcelFileDescriptor oldState,
- ParcelFileDescriptor data,
- ParcelFileDescriptor newState) {
+ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
Log.d(TAG, "onBackup");
+ FileBackupHelper.performBackup(this, oldState, data, newState, new String[] {
+ BackupTestActivity.FILE_NAME
+ });
}
@Override
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 2d8471b..2eb7a1d 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -38,6 +38,8 @@
mAssetSourceDir(NULL),
mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
mRClassDir(NULL), mResourceIntermediatesDir(NULL),
+ mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
+ mVersionCode(NULL), mVersionName(NULL),
mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -99,6 +101,17 @@
const android::Vector<const char*>& getNoCompressExtensions() const { return mNoCompressExtensions; }
void addNoCompressExtension(const char* ext) { mNoCompressExtensions.add(ext); }
+ const char* getMinSdkVersion() const { return mMinSdkVersion; }
+ void setMinSdkVersion(const char* val) { mMinSdkVersion = val; }
+ const char* getTargetSdkVersion() const { return mTargetSdkVersion; }
+ void setTargetSdkVersion(const char* val) { mTargetSdkVersion = val; }
+ const char* getMaxSdkVersion() const { return mMaxSdkVersion; }
+ void setMaxSdkVersion(const char* val) { mMaxSdkVersion = val; }
+ const char* getVersionCode() const { return mVersionCode; }
+ void setVersionCode(const char* val) { mVersionCode = val; }
+ const char* getVersionName() const { return mVersionName; }
+ void setVersionName(const char* val) { mVersionName = val; }
+
/*
* Set and get the file specification.
*
@@ -151,6 +164,12 @@
android::Vector<const char*> mNoCompressExtensions;
android::Vector<const char*> mResourceSourceDirs;
+ const char* mMinSdkVersion;
+ const char* mTargetSdkVersion;
+ const char* mMaxSdkVersion;
+ const char* mVersionCode;
+ const char* mVersionName;
+
/* file specification */
int mArgc;
char* const* mArgv;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 6f3461d..dc91a48 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -268,17 +268,19 @@
return str ? String8(str, len) : String8();
}
-static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes, String8* outError)
+static int32_t getIntegerAttribute(const ResXMLTree& tree, uint32_t attrRes,
+ String8* outError, int32_t defValue = -1)
{
ssize_t idx = indexOfAttribute(tree, attrRes);
if (idx < 0) {
- return -1;
+ return defValue;
}
Res_value value;
if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
- if (value.dataType != Res_value::TYPE_INT_DEC) {
+ if (value.dataType < Res_value::TYPE_FIRST_INT
+ || value.dataType > Res_value::TYPE_LAST_INT) {
if (outError != NULL) *outError = "attribute is not an integer value";
- return -1;
+ return defValue;
}
}
return value.data;
@@ -318,7 +320,15 @@
VERSION_NAME_ATTR = 0x0101021c,
LABEL_ATTR = 0x01010001,
ICON_ATTR = 0x01010002,
- MIN_SDK_VERSION_ATTR = 0x0101020c
+ MIN_SDK_VERSION_ATTR = 0x0101020c,
+ REQ_TOUCH_SCREEN_ATTR = 0x01010227,
+ REQ_KEYBOARD_TYPE_ATTR = 0x01010228,
+ REQ_HARD_KEYBOARD_ATTR = 0x01010229,
+ REQ_NAVIGATION_ATTR = 0x0101022a,
+ REQ_FIVE_WAY_NAV_ATTR = 0x01010232,
+ TARGET_SDK_VERSION_ATTR = 0x01010270,
+ TEST_ONLY_ATTR = 0x01010272,
+ DENSITY_ATTR = 0x0101026c,
};
const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@ -357,7 +367,8 @@
const char* filename = bundle->getFileSpecEntry(1);
AssetManager assets;
- if (!assets.addAssetPath(String8(filename), NULL)) {
+ void* assetsCookie;
+ if (!assets.addAssetPath(String8(filename), &assetsCookie)) {
fprintf(stderr, "ERROR: dump failed because assets could not be loaded\n");
return 1;
}
@@ -543,15 +554,77 @@
goto bail;
}
printf("icon='%s'\n", icon.string());
- } else if (tag == "uses-sdk") {
- int32_t sdkVersion = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
+ int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0);
if (error != "") {
- fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n", error.string());
+ fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
goto bail;
}
- if (sdkVersion != -1) {
- printf("sdkVersion:'%d'\n", sdkVersion);
+ if (testOnly != 0) {
+ printf("testOnly='%d'\n", testOnly);
}
+ } else if (tag == "uses-sdk") {
+ int32_t code = getIntegerAttribute(tree, MIN_SDK_VERSION_ATTR, &error);
+ if (error != "") {
+ error = "";
+ String8 name = getResolvedAttribute(&res, tree, MIN_SDK_VERSION_ATTR, &error);
+ if (error != "") {
+ fprintf(stderr, "ERROR getting 'android:minSdkVersion' attribute: %s\n",
+ error.string());
+ goto bail;
+ }
+ printf("sdkVersion:'%s'\n", name.string());
+ } else if (code != -1) {
+ printf("sdkVersion:'%d'\n", code);
+ }
+ code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error);
+ if (error != "") {
+ error = "";
+ String8 name = getResolvedAttribute(&res, tree, TARGET_SDK_VERSION_ATTR, &error);
+ if (error != "") {
+ fprintf(stderr, "ERROR getting 'android:targetSdkVersion' attribute: %s\n",
+ error.string());
+ goto bail;
+ }
+ printf("targetSdkVersion:'%s'\n", name.string());
+ } else if (code != -1) {
+ printf("targetSdkVersion:'%d'\n", code);
+ }
+ } else if (tag == "uses-configuration") {
+ int32_t reqTouchScreen = getIntegerAttribute(tree,
+ REQ_TOUCH_SCREEN_ATTR, NULL, 0);
+ int32_t reqKeyboardType = getIntegerAttribute(tree,
+ REQ_KEYBOARD_TYPE_ATTR, NULL, 0);
+ int32_t reqHardKeyboard = getIntegerAttribute(tree,
+ REQ_HARD_KEYBOARD_ATTR, NULL, 0);
+ int32_t reqNavigation = getIntegerAttribute(tree,
+ REQ_NAVIGATION_ATTR, NULL, 0);
+ int32_t reqFiveWayNav = getIntegerAttribute(tree,
+ REQ_FIVE_WAY_NAV_ATTR, NULL, 0);
+ printf("uses-configuation:");
+ if (reqTouchScreen != 0) {
+ printf(" reqTouchScreen='%d'", reqTouchScreen);
+ }
+ if (reqKeyboardType != 0) {
+ printf(" reqKeyboardType='%d'", reqKeyboardType);
+ }
+ if (reqHardKeyboard != 0) {
+ printf(" reqHardKeyboard='%d'", reqHardKeyboard);
+ }
+ if (reqNavigation != 0) {
+ printf(" reqNavigation='%d'", reqNavigation);
+ }
+ if (reqFiveWayNav != 0) {
+ printf(" reqFiveWayNav='%d'", reqFiveWayNav);
+ }
+ printf("\n");
+ } else if (tag == "supports-density") {
+ int32_t dens = getIntegerAttribute(tree, DENSITY_ATTR, &error);
+ if (error != "") {
+ fprintf(stderr, "ERROR getting 'android:density' attribute: %s\n",
+ error.string());
+ goto bail;
+ }
+ printf("supports-density:'%d'\n", dens);
}
} else if (depth == 3 && withinApplication) {
withinActivity = false;
@@ -592,18 +665,18 @@
}
}
} else if (depth == 5) {
- if (withinActivity) {
- if (tag == "action") {
- //printf("LOG: action tag\n");
- String8 action = getAttribute(tree, NAME_ATTR, &error);
- if (error != "") {
- fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
- goto bail;
- }
- if (action == "android.intent.action.MAIN") {
- isMainActivity = true;
- //printf("LOG: isMainActivity==true\n");
- }
+ if (withinActivity) {
+ if (tag == "action") {
+ //printf("LOG: action tag\n");
+ String8 action = getAttribute(tree, NAME_ATTR, &error);
+ if (error != "") {
+ fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
+ goto bail;
+ }
+ if (action == "android.intent.action.MAIN") {
+ isMainActivity = true;
+ //printf("LOG: isMainActivity==true\n");
+ }
} else if (tag == "category") {
String8 category = getAttribute(tree, NAME_ATTR, &error);
if (error != "") {
@@ -671,6 +744,17 @@
printf(" '%s'", localeStr);
}
printf("\n");
+ AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib");
+ if (dir != NULL) {
+ if (dir->getFileCount() > 0) {
+ printf("native-code:");
+ for (size_t i=0; i<dir->getFileCount(); i++) {
+ printf(" '%s'", dir->getFileName(i).string());
+ }
+ printf("\n");
+ }
+ delete dir;
+ }
} else if (strcmp("configurations", option) == 0) {
Vector<ResTable_config> configs;
res.getConfigurations(&configs);
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 71b1a3c..8bf2b07 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -54,9 +54,10 @@
" xmlstrings Print the strings of the given compiled xml assets.\n\n", gProgName);
fprintf(stderr,
" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
- " [-0 extension [-0 extension ...]] \\\n"
- " [-g tolerance] \\\n"
- " [-j jarfile] \\\n"
+ " [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
+ " [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
+ " [--max-sdk-version VAL] [--app-version VAL] \\\n"
+ " [--app-version-name TEXT] \\\n"
" [-I base-package [-I base-package ...]] \\\n"
" [-A asset-source-dir] [-P public-definitions-file] \\\n"
" [-S resource-sources [-S resource-sources ...]] "
@@ -115,7 +116,17 @@
" and the first match found (left to right) will take precedence."
" -0 specifies an additional extension for which such files will not\n"
" be stored compressed in the .apk. An empty string means to not\n"
- " compress any files at all.\n");
+ " compress any files at all.\n"
+ " --min-sdk-version\n"
+ " inserts android:minSdkVersion in to manifest.\n"
+ " --target-sdk-version\n"
+ " inserts android:targetSdkVersion in to manifest.\n"
+ " --max-sdk-version\n"
+ " inserts android:maxSdkVersion in to manifest.\n"
+ " --version-code\n"
+ " inserts android:versionCode in to manifest.\n"
+ " --version-name\n"
+ " inserts android:versionName in to manifest.\n");
}
/*
@@ -339,6 +350,59 @@
bundle.setCompressionMethod(ZipEntry::kCompressStored);
}
break;
+ case '-':
+ if (strcmp(cp, "-min-sdk-version") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--min-sdk-version' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setMinSdkVersion(argv[0]);
+ } else if (strcmp(cp, "-target-sdk-version") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--target-sdk-version' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setTargetSdkVersion(argv[0]);
+ } else if (strcmp(cp, "-max-sdk-version") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--max-sdk-version' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setMaxSdkVersion(argv[0]);
+ } else if (strcmp(cp, "-version-code") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--version-code' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setVersionCode(argv[0]);
+ } else if (strcmp(cp, "-version-name") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--version-name' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setVersionName(argv[0]);
+ } else {
+ fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
+ wantUsage = true;
+ goto bail;
+ }
+ cp += strlen(cp) - 1;
+ break;
default:
fprintf(stderr, "ERROR: Unknown flag '-%c'\n", *cp);
wantUsage = true;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index b2bd9ff..49ccf71 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -495,6 +495,58 @@
return;
}
+void addTagAttribute(const sp<XMLNode>& node, const char* ns8,
+ const char* attr8, const char* value)
+{
+ if (value == NULL) {
+ return;
+ }
+
+ const String16 ns(ns8);
+ const String16 attr(attr8);
+
+ if (node->getAttribute(ns, attr) != NULL) {
+ fprintf(stderr, "Warning: AndroidManifest.xml already defines %s (in %s)\n",
+ String8(attr).string(), String8(ns).string());
+ return;
+ }
+
+ node->addAttribute(ns, attr, String16(value));
+}
+
+status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
+{
+ root = root->searchElement(String16(), String16("manifest"));
+ if (root == NULL) {
+ fprintf(stderr, "No <manifest> tag.\n");
+ return UNKNOWN_ERROR;
+ }
+
+ addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
+ bundle->getVersionCode());
+ addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
+ bundle->getVersionName());
+
+ if (bundle->getMinSdkVersion() != NULL
+ || bundle->getTargetSdkVersion() != NULL
+ || bundle->getMaxSdkVersion() != NULL) {
+ sp<XMLNode> vers = root->getChildElement(String16(), String16("uses-sdk"));
+ if (vers == NULL) {
+ vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
+ root->insertChildAt(vers, 0);
+ }
+
+ addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
+ bundle->getMinSdkVersion());
+ addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "targetSdkVersion",
+ bundle->getTargetSdkVersion());
+ addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion",
+ bundle->getMaxSdkVersion());
+ }
+
+ return NO_ERROR;
+}
+
#define ASSIGN_IT(n) \
do { \
ssize_t index = resources->indexOfKey(String8(#n)); \
@@ -1013,7 +1065,15 @@
// Generate final compiled manifest file.
manifestFile->clearData();
- err = compileXmlFile(assets, manifestFile, &table);
+ sp<XMLNode> manifestTree = XMLNode::parse(manifestFile);
+ if (manifestTree == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ err = massageManifest(bundle, manifestTree);
+ if (err < NO_ERROR) {
+ return err;
+ }
+ err = compileXmlFile(assets, manifestTree, manifestFile, &table);
if (err < NO_ERROR) {
return err;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index ef11a83..25ab147 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -23,6 +23,16 @@
if (root == NULL) {
return UNKNOWN_ERROR;
}
+
+ return compileXmlFile(assets, root, target, table, options);
+}
+
+status_t compileXmlFile(const sp<AaptAssets>& assets,
+ const sp<XMLNode>& root,
+ const sp<AaptFile>& target,
+ ResourceTable* table,
+ int options)
+{
if ((options&XML_COMPILE_STRIP_WHITESPACE) != 0) {
root->removeWhitespace(true, NULL);
} else if ((options&XML_COMPILE_COMPACT_WHITESPACE) != 0) {
@@ -1307,7 +1317,7 @@
} else if (id != 0) {
if (id == 127) {
if (mHaveAppPackage) {
- fprintf(stderr, "Included resource have two application packages!\n");
+ fprintf(stderr, "Included resources have two application packages!\n");
return UNKNOWN_ERROR;
}
mHaveAppPackage = true;
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index 74ba326..665232b 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -15,6 +15,7 @@
using namespace std;
+class XMLNode;
class ResourceTable;
enum {
@@ -34,6 +35,12 @@
ResourceTable* table,
int options = XML_COMPILE_STANDARD_RESOURCE);
+status_t compileXmlFile(const sp<AaptAssets>& assets,
+ const sp<XMLNode>& xmlTree,
+ const sp<AaptFile>& target,
+ ResourceTable* table,
+ int options = XML_COMPILE_STANDARD_RESOURCE);
+
status_t compileResourceFile(Bundle* bundle,
const sp<AaptAssets>& assets,
const sp<AaptFile>& in,
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index d476567..2a85bc7 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -524,12 +524,30 @@
return mChildren;
}
+const String8& XMLNode::getFilename() const
+{
+ return mFilename;
+}
+
const Vector<XMLNode::attribute_entry>&
XMLNode::getAttributes() const
{
return mAttributes;
}
+const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns,
+ const String16& name) const
+{
+ for (size_t i=0; i<mAttributes.size(); i++) {
+ const attribute_entry& ae(mAttributes.itemAt(i));
+ if (ae.ns == ns && ae.name == name) {
+ return &ae;
+ }
+ }
+
+ return NULL;
+}
+
const String16& XMLNode::getCData() const
{
return mChars;
@@ -550,6 +568,38 @@
return mEndLineNumber;
}
+sp<XMLNode> XMLNode::searchElement(const String16& tagNamespace, const String16& tagName)
+{
+ if (getType() == XMLNode::TYPE_ELEMENT
+ && mNamespaceUri == tagNamespace
+ && mElementName == tagName) {
+ return this;
+ }
+
+ for (size_t i=0; i<mChildren.size(); i++) {
+ sp<XMLNode> found = mChildren.itemAt(i)->searchElement(tagNamespace, tagName);
+ if (found != NULL) {
+ return found;
+ }
+ }
+
+ return NULL;
+}
+
+sp<XMLNode> XMLNode::getChildElement(const String16& tagNamespace, const String16& tagName)
+{
+ for (size_t i=0; i<mChildren.size(); i++) {
+ sp<XMLNode> child = mChildren.itemAt(i);
+ if (child->getType() == XMLNode::TYPE_ELEMENT
+ && child->mNamespaceUri == tagNamespace
+ && child->mElementName == tagName) {
+ return child;
+ }
+ }
+
+ return NULL;
+}
+
status_t XMLNode::addChild(const sp<XMLNode>& child)
{
if (getType() == TYPE_CDATA) {
@@ -561,6 +611,17 @@
return NO_ERROR;
}
+status_t XMLNode::insertChildAt(const sp<XMLNode>& child, size_t index)
+{
+ if (getType() == TYPE_CDATA) {
+ SourcePos(mFilename, child->getStartLineNumber()).error("Child to CDATA node.");
+ return UNKNOWN_ERROR;
+ }
+ //printf("Adding child %p to parent %p\n", child.get(), this);
+ mChildren.insertAt(child, index);
+ return NO_ERROR;
+}
+
status_t XMLNode::addAttribute(const String16& ns, const String16& name,
const String16& value)
{
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index 86548a2..a9bea43 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -68,6 +68,8 @@
const String16& getElementName() const;
const Vector<sp<XMLNode> >& getChildren() const;
+ const String8& getFilename() const;
+
struct attribute_entry {
attribute_entry() : index(~(uint32_t)0), nameResId(0)
{
@@ -91,6 +93,8 @@
const Vector<attribute_entry>& getAttributes() const;
+ const attribute_entry* getAttribute(const String16& ns, const String16& name) const;
+
const String16& getCData() const;
const String16& getComment() const;
@@ -98,8 +102,14 @@
int32_t getStartLineNumber() const;
int32_t getEndLineNumber() const;
+ sp<XMLNode> searchElement(const String16& tagNamespace, const String16& tagName);
+
+ sp<XMLNode> getChildElement(const String16& tagNamespace, const String16& tagName);
+
status_t addChild(const sp<XMLNode>& child);
+ status_t insertChildAt(const sp<XMLNode>& child, size_t index);
+
status_t addAttribute(const String16& ns, const String16& name,
const String16& value);
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index f9a0845..00829d6 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -69,5 +69,11 @@
boolean acquireWifiLock(IBinder lock, int lockType, String tag);
boolean releaseWifiLock(IBinder lock);
+
+ boolean isWifiMulticastEnabled();
+
+ void enableWifiMulticast(IBinder binder, String tag);
+
+ void disableWifiMulticast();
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index a51e88f..658a7b2 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -823,4 +823,65 @@
public WifiLock createWifiLock(String tag) {
return new WifiLock(WIFI_MODE_FULL, tag);
}
+
+ /**
+ * Check multicast filter status.
+ *
+ * @return true if multicast packets are allowed.
+ *
+ * @hide pending API council approval
+ */
+ public boolean isWifiMulticastEnabled() {
+ try {
+ return mService.isWifiMulticastEnabled();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Turn on the reception of multicast packets.
+ * The default behavior is to disable multicast packets as they
+ * have a noticable negative effect on battery life. An
+ * application can turn them on, but should not leave it on for longer
+ * than needed. When the app quits (or crashes) its request will
+ * be reverted.
+ *
+ * @param tag a string associated with this request for debugging.
+ *
+ * @return true on success
+ *
+ * @see #disableWifiMulticast
+ *
+ * @hide pending API council approval
+ */
+ public boolean enableWifiMulticast(String tag) {
+ try {
+ mService.enableWifiMulticast(new Binder(), tag);
+ return true;
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Return to the default multicast-off setting.
+ * Note that if others had turned on Multicast reception, your
+ * call will not turn it back off - they must also turn off their
+ * request for multicast reception.
+ *
+ * @return true on success
+ *
+ * @see #enableWifiMulticast
+ *
+ * @hide pending API council approval
+ */
+ public boolean disableWifiMulticast() {
+ try {
+ mService.disableWifiMulticast();
+ return true;
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 6ea35f5..4073ddc 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -161,8 +161,8 @@
private WifiInfo mWifiInfo;
private List<ScanResult> mScanResults;
private WifiManager mWM;
- private boolean mHaveIPAddress;
- private boolean mObtainingIPAddress;
+ private boolean mHaveIpAddress;
+ private boolean mObtainingIpAddress;
private boolean mTornDownByConnMgr;
/**
* A DISCONNECT event has been received, but processing it
@@ -303,8 +303,8 @@
mWifiInfo = new WifiInfo();
mWifiMonitor = new WifiMonitor(this);
- mHaveIPAddress = false;
- mObtainingIPAddress = false;
+ mHaveIpAddress = false;
+ mObtainingIpAddress = false;
setTornDownByConnMgr(false);
mDisconnectPending = false;
mScanResults = new ArrayList<ScanResult>();
@@ -444,6 +444,14 @@
}
/**
+ * Report whether the Wi-Fi connection has successfully acquired an IP address.
+ * @return {@code true} if the Wi-Fi connection has been assigned an IP address.
+ */
+ public boolean hasIpAddress() {
+ return mHaveIpAddress;
+ }
+
+ /**
* Send the tracker a notification that a user-entered password key
* may be incorrect (i.e., caused authentication to fail).
*/
@@ -724,7 +732,7 @@
intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, true);
mContext.sendBroadcast(intent);
}
- if (supplState == SupplicantState.COMPLETED && mHaveIPAddress) {
+ if (supplState == SupplicantState.COMPLETED && mHaveIpAddress) {
setDetailedState(DetailedState.CONNECTED);
} else {
setDetailedState(WifiInfo.getDetailedStateOf(supplState));
@@ -732,15 +740,19 @@
/*
* Filter out multicast packets. This saves battery power, since
* the CPU doesn't have to spend time processing packets that
- * are going to end up being thrown away. Obviously, if we
- * ever want to support multicast, this will have to change.
+ * are going to end up being thrown away.
+ *
+ * Note that rather than turn this off directly, we use the
+ * public api - this keeps us all in sync - turn multicast on
+ * first and then off.. if nobody else wants it on it'll be
+ * off then and it's all synchronized within the API.
*/
+ mWM.enableWifiMulticast("WifiStateTracker");
+ mWM.disableWifiMulticast();
+
if (mBluetoothA2dp == null) {
mBluetoothA2dp = new BluetoothA2dp(mContext);
}
- synchronized (this) {
- WifiNative.startPacketFiltering();
- }
checkIsBluetoothPlaying();
break;
@@ -779,8 +791,8 @@
}
setDetailedState(DetailedState.DISCONNECTED);
setSupplicantState(SupplicantState.UNINITIALIZED);
- mHaveIPAddress = false;
- mObtainingIPAddress = false;
+ mHaveIpAddress = false;
+ mObtainingIpAddress = false;
if (died) {
mWM.setWifiEnabled(false);
}
@@ -950,7 +962,7 @@
}
requestConnectionStatus(mWifiInfo);
if (!(result.state == DetailedState.CONNECTED &&
- (!mHaveIPAddress || mDisconnectPending))) {
+ (!mHaveIpAddress || mDisconnectPending))) {
setDetailedState(result.state);
}
@@ -979,7 +991,7 @@
mLastBssid = result.BSSID;
mLastSsid = mWifiInfo.getSSID();
mLastNetworkId = result.networkId;
- if (mHaveIPAddress) {
+ if (mHaveIpAddress) {
setDetailedState(DetailedState.CONNECTED);
} else {
setDetailedState(DetailedState.OBTAINING_IPADDR);
@@ -1047,8 +1059,8 @@
break;
}
mReconnectCount = 0;
- mHaveIPAddress = true;
- mObtainingIPAddress = false;
+ mHaveIpAddress = true;
+ mObtainingIpAddress = false;
mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
mLastSignalLevel = -1; // force update of signal strength
if (mNetworkInfo.getDetailedState() != DetailedState.CONNECTED) {
@@ -1074,9 +1086,9 @@
// [ 0- 0] Interface configuration succeeded (1) or failed (0)
EventLog.writeEvent(EVENTLOG_INTERFACE_CONFIGURATION_STATE_CHANGED, 0);
- mHaveIPAddress = false;
+ mHaveIpAddress = false;
mWifiInfo.setIpAddress(0);
- mObtainingIPAddress = false;
+ mObtainingIpAddress = false;
synchronized(this) {
WifiNative.disconnectCommand();
}
@@ -1152,18 +1164,18 @@
setPollTimer();
mLastSignalLevel = -1;
if (!mUseStaticIp) {
- if (!mHaveIPAddress && !mObtainingIPAddress) {
- mObtainingIPAddress = true;
+ if (!mHaveIpAddress && !mObtainingIpAddress) {
+ mObtainingIpAddress = true;
mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);
}
} else {
int event;
if (NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) {
- mHaveIPAddress = true;
+ mHaveIpAddress = true;
event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;
if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration succeeded");
} else {
- mHaveIPAddress = false;
+ mHaveIpAddress = false;
event = EVENT_INTERFACE_CONFIGURATION_FAILED;
if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration failed");
}
@@ -1196,8 +1208,8 @@
* using the interface, stopping DHCP, and disabling the interface.
*/
public void resetInterface() {
- mHaveIPAddress = false;
- mObtainingIPAddress = false;
+ mHaveIpAddress = false;
+ mObtainingIpAddress = false;
mWifiInfo.setIpAddress(0);
/*
@@ -1608,8 +1620,8 @@
}
sb.append(LS).append(mWifiInfo).append(LS);
sb.append(mDhcpInfo).append(LS);
- sb.append("haveIpAddress=").append(mHaveIPAddress).
- append(", obtainingIpAddress=").append(mObtainingIPAddress).
+ sb.append("haveIpAddress=").append(mHaveIpAddress).
+ append(", obtainingIpAddress=").append(mObtainingIpAddress).
append(", scanModeActive=").append(mIsScanModeActive).append(LS).
append("lastSignalLevel=").append(mLastSignalLevel).
append(", explicitlyDisabled=").append(mTornDownByConnMgr);