Merge "Remove const_cast to layer handle"
diff --git a/api/current.xml b/api/current.xml
index 2427376..7d7bec1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2539,6 +2539,17 @@
visibility="public"
>
</field>
+<field name="borderlessButtonStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843580"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="bottom"
type="int"
transient="false"
@@ -3562,6 +3573,28 @@
visibility="public"
>
</field>
+<field name="dividerHorizontal"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843581"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="dividerPadding"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843579"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dividerVertical"
type="int"
transient="false"
@@ -8391,6 +8424,17 @@
visibility="public"
>
</field>
+<field name="showDividers"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843578"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="showSilent"
type="int"
transient="false"
@@ -15520,6 +15564,17 @@
visibility="public"
>
</field>
+<field name="Widget_Holo_Button_Borderless"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974047"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_Holo_Button_Inset"
type="int"
transient="false"
@@ -20749,6 +20804,19 @@
visibility="public"
>
</constructor>
+<method name="addOnMenuVisibilityListener"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.app.ActionBar.OnMenuVisibilityListener">
+</parameter>
+</method>
<method name="addTab"
return="void"
abstract="true"
@@ -20998,6 +21066,19 @@
visibility="public"
>
</method>
+<method name="removeOnMenuVisibilityListener"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.app.ActionBar.OnMenuVisibilityListener">
+</parameter>
+</method>
<method name="removeTab"
return="void"
abstract="true"
@@ -21131,7 +21212,7 @@
>
<parameter name="adapter" type="android.widget.SpinnerAdapter">
</parameter>
-<parameter name="callback" type="android.app.ActionBar.NavigationCallback">
+<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
</parameter>
</method>
<method name="setDropdownNavigationMode"
@@ -21146,7 +21227,7 @@
>
<parameter name="adapter" type="android.widget.SpinnerAdapter">
</parameter>
-<parameter name="callback" type="android.app.ActionBar.NavigationCallback">
+<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
</parameter>
<parameter name="defaultSelectedPosition" type="int">
</parameter>
@@ -21163,7 +21244,7 @@
>
<parameter name="adapter" type="android.widget.SpinnerAdapter">
</parameter>
-<parameter name="callback" type="android.app.ActionBar.NavigationCallback">
+<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
</parameter>
</method>
<method name="setNavigationMode"
@@ -21475,7 +21556,28 @@
>
</field>
</class>
-<interface name="ActionBar.NavigationCallback"
+<interface name="ActionBar.OnMenuVisibilityListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onMenuVisibilityChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="isVisible" type="boolean">
+</parameter>
+</method>
+</interface>
+<interface name="ActionBar.OnNavigationListener"
abstract="true"
static="true"
final="false"
@@ -23181,6 +23283,17 @@
<parameter name="exitAnim" type="int">
</parameter>
</method>
+<method name="recreate"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="registerForContextMenu"
return="void"
abstract="false"
@@ -89705,6 +89818,17 @@
visibility="public"
>
</method>
+<method name="getPreferredPreviewSizeForVideo"
+ return="android.hardware.Camera.Size"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getPreviewFormat"
return="int"
abstract="false"
@@ -89894,6 +90018,17 @@
visibility="public"
>
</method>
+<method name="getSupportedVideoSizes"
+ return="java.util.List<android.hardware.Camera.Size>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getSupportedWhiteBalance"
return="java.util.List<java.lang.String>"
abstract="false"
@@ -160999,6 +161134,468 @@
>
</field>
</interface>
+<class name="Ptp"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Ptp"
+ type="android.provider.Ptp"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="AUTHORITY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""ptp""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Ptp.Device"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.provider.BaseColumns">
+</implements>
+<constructor name="Ptp.Device"
+ type="android.provider.Ptp.Device"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+</method>
+<field name="CONTENT_URI"
+ type="android.net.Uri"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MANUFACTURER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""manufacturer""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODEL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""model""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Ptp.Object"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.provider.BaseColumns">
+</implements>
+<constructor name="Ptp.Object"
+ type="android.provider.Ptp.Object"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+<parameter name="objectID" type="long">
+</parameter>
+</method>
+<method name="getContentUriForImport"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+<parameter name="objectID" type="long">
+</parameter>
+<parameter name="destPath" type="java.lang.String">
+</parameter>
+</method>
+<method name="getContentUriForObjectChildren"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+<parameter name="objectID" type="long">
+</parameter>
+</method>
+<method name="getContentUriForStorageChildren"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+<parameter name="storageID" type="long">
+</parameter>
+</method>
+<field name="ASSOCIATION_DESC"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""association_desc""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ASSOCIATION_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""association_type""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DATE_CREATED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""date_created""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DATE_MODIFIED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""date_modified""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FORMAT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""format""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IMAGE_DEPTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""image_depth""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IMAGE_HEIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""image_height""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IMAGE_WIDTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""image_width""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEYWORDS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""keywords""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NAME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""name""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PARENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""parent""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PROTECTION_STATUS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""protection_status""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SEQUENCE_NUMBER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""sequence_number""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""size""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STORAGE_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""storage_id""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="THUMB"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""thumb""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="THUMB_FORMAT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""thumb_format""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="THUMB_HEIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""thumb_height""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="THUMB_SIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""thumb_size""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="THUMB_WIDTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""thumb_width""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Ptp.Storage"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.provider.BaseColumns">
+</implements>
+<constructor name="Ptp.Storage"
+ type="android.provider.Ptp.Storage"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+</method>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="deviceID" type="int">
+</parameter>
+<parameter name="storageID" type="long">
+</parameter>
+</method>
+<field name="DESCRIPTION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""description""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IDENTIFIER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""identifier""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="SearchRecentSuggestions"
extends="java.lang.Object"
abstract="false"
@@ -194809,6 +195406,17 @@
visibility="public"
>
</method>
+<method name="getLocalState"
+ return="java.lang.Object"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getResult"
return="boolean"
abstract="false"
@@ -208810,6 +209418,8 @@
</parameter>
<parameter name="myWindowOnly" type="boolean">
</parameter>
+<parameter name="myLocalState" type="java.lang.Object">
+</parameter>
</method>
<method name="unscheduleDrawable"
return="void"
@@ -236836,6 +237446,17 @@
visibility="public"
>
</method>
+<method name="getShowDividers"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getWeightSum"
return="float"
abstract="false"
@@ -236916,6 +237537,19 @@
<parameter name="i" type="int">
</parameter>
</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="divider" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
<method name="setGravity"
return="void"
abstract="false"
@@ -236968,6 +237602,19 @@
<parameter name="orientation" type="int">
</parameter>
</method>
+<method name="setShowDividers"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="showDividers" type="int">
+</parameter>
+</method>
<method name="setVerticalGravity"
return="void"
abstract="false"
@@ -237005,6 +237652,50 @@
visibility="public"
>
</field>
+<field name="SHOW_DIVIDER_BEGINNING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SHOW_DIVIDER_END"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SHOW_DIVIDER_MIDDLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SHOW_DIVIDER_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="VERTICAL"
type="int"
transient="false"
@@ -238771,7 +239462,35 @@
>
<parameter name="context" type="android.content.Context">
</parameter>
-<parameter name="interpolator" type="android.graphics.Interpolator">
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+<parameter name="bounceCoefficientX" type="float">
+</parameter>
+<parameter name="bounceCoefficientY" type="float">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
</parameter>
<parameter name="bounceCoefficientX" type="float">
</parameter>
@@ -245106,19 +245825,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="drawable" type="android.graphics.drawable.Drawable">
-</parameter>
-</method>
-<method name="setDividerDrawable"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
<parameter name="resId" type="int">
</parameter>
</method>
@@ -245916,6 +246622,17 @@
visibility="public"
>
</method>
+<method name="getCustomSelectionActionModeCallback"
+ return="android.view.ActionMode.Callback"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDefaultEditable"
return="boolean"
abstract="false"
@@ -246714,6 +247431,19 @@
<parameter name="visible" type="boolean">
</parameter>
</method>
+<method name="setCustomSelectionActionModeCallback"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="actionModeCallback" type="android.view.ActionMode.Callback">
+</parameter>
+</method>
<method name="setEditableFactory"
return="void"
abstract="false"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 040421a..f62db1c 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -341,9 +341,11 @@
if (nonLocalized != null) {
return nonLocalized.toString();
}
- Resources r = getResources(pii);
- if (r != null) {
- return r.getString(res);
+ if (res != 0) {
+ Resources r = getResources(pii);
+ if (r != null) {
+ return r.getString(res);
+ }
}
return null;
}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 7a6ad0f..2f69520 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -168,13 +168,13 @@
* @param adapter An adapter that will provide views both to display
* the current navigation selection and populate views
* within the dropdown navigation menu.
- * @param callback A NavigationCallback that will receive events when the user
+ * @param callback A OnNavigationListener that will receive events when the user
* selects a navigation item.
* @deprecated See setListNavigationCallbacks.
*/
@Deprecated
public abstract void setDropdownNavigationMode(SpinnerAdapter adapter,
- NavigationCallback callback);
+ OnNavigationListener callback);
/**
* Set the adapter and navigation callback for list navigation mode.
@@ -182,17 +182,17 @@
* The supplied adapter will provide views for the expanded list as well as
* the currently selected item. (These may be displayed differently.)
*
- * The supplied NavigationCallback will alert the application when the user
+ * The supplied OnNavigationListener will alert the application when the user
* changes the current list selection.
*
* @param adapter An adapter that will provide views both to display
* the current navigation selection and populate views
* within the dropdown navigation menu.
- * @param callback A NavigationCallback that will receive events when the user
+ * @param callback An OnNavigationListener that will receive events when the user
* selects a navigation item.
*/
public abstract void setListNavigationCallbacks(SpinnerAdapter adapter,
- NavigationCallback callback);
+ OnNavigationListener callback);
/**
* Set the action bar into dropdown navigation mode and supply an adapter that will
@@ -201,7 +201,7 @@
* @param adapter An adapter that will provide views both to display the current
* navigation selection and populate views within the dropdown
* navigation menu.
- * @param callback A NavigationCallback that will receive events when the user
+ * @param callback A OnNavigationListener that will receive events when the user
* selects a navigation item.
* @param defaultSelectedPosition Position within the provided adapter that should be
* selected from the outset.
@@ -209,7 +209,7 @@
*/
@Deprecated
public abstract void setDropdownNavigationMode(SpinnerAdapter adapter,
- NavigationCallback callback, int defaultSelectedPosition);
+ OnNavigationListener callback, int defaultSelectedPosition);
/**
* Set the selected navigation item in list or tabbed navigation modes.
@@ -532,9 +532,24 @@
public abstract boolean isShowing();
/**
- * Callback interface for ActionBar navigation events.
+ * Add a listener that will respond to menu visibility change events.
+ *
+ * @param listener The new listener to add
*/
- public interface NavigationCallback {
+ public abstract void addOnMenuVisibilityListener(OnMenuVisibilityListener listener);
+
+ /**
+ * Remove a menu visibility listener. This listener will no longer receive menu
+ * visibility change events.
+ *
+ * @param listener A listener to remove that was previously added
+ */
+ public abstract void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener);
+
+ /**
+ * Listener interface for ActionBar navigation events.
+ */
+ public interface OnNavigationListener {
/**
* This method is called whenever a navigation item in your action bar
* is selected.
@@ -547,6 +562,21 @@
}
/**
+ * Listener for receiving events when action bar menus are shown or hidden.
+ */
+ public interface OnMenuVisibilityListener {
+ /**
+ * Called when an action bar menu is shown or hidden. Applications may want to use
+ * this to tune auto-hiding behavior for the action bar or pause/resume video playback,
+ * gameplay, or other activity within the main content area.
+ *
+ * @param isVisible True if an action bar menu is now visible, false if no action bar
+ * menus are visible.
+ */
+ public void onMenuVisibilityChanged(boolean isVisible);
+ }
+
+ /**
* A tab in the action bar.
*
* <p>Tabs manage the hiding and showing of {@link Fragment}s.
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d69a179..0a2e031 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -42,6 +42,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Parcelable;
import android.os.RemoteException;
import android.text.Selection;
@@ -78,6 +79,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
/**
* An activity is a single, focused thing that the user can do. Almost all
@@ -842,8 +844,6 @@
* @see #onPostCreate
*/
protected void onCreate(Bundle savedInstanceState) {
- mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
- com.android.internal.R.styleable.Window_windowNoDisplay, false);
if (mLastNonConfigurationInstances != null) {
mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
}
@@ -2362,6 +2362,9 @@
* @return The default implementation returns true.
*/
public boolean onMenuOpened(int featureId, Menu menu) {
+ if (featureId == Window.FEATURE_ACTION_BAR) {
+ mActionBar.dispatchMenuVisibilityChanged(true);
+ }
return true;
}
@@ -2392,7 +2395,7 @@
return true;
}
return mFragments.dispatchContextItemSelected(item);
-
+
default:
return false;
}
@@ -2417,6 +2420,10 @@
case Window.FEATURE_CONTEXT_MENU:
onContextMenuClosed(menu);
break;
+
+ case Window.FEATURE_ACTION_BAR:
+ mActionBar.dispatchMenuVisibilityChanged(false);
+ break;
}
}
@@ -3502,6 +3509,22 @@
}
/**
+ * Cause this Activity to be recreated with a new instance. This results
+ * in essentially the same flow as when the Activity is created due to
+ * a configuration change -- the current instance will go through its
+ * lifecycle to {@link #onDestroy} and a new instance then created after it.
+ */
+ public void recreate() {
+ if (mParent != null) {
+ throw new IllegalStateException("Can only be called on top-level activity");
+ }
+ if (Looper.myLooper() != mMainThread.getLooper()) {
+ throw new IllegalStateException("Must be called from main thread");
+ }
+ mMainThread.requestRelaunchActivity(mToken, null, null, 0, false, null, false);
+ }
+
+ /**
* Call this when your activity is done and should be closed. The
* ActivityResult is propagated back to whoever launched you via
* onActivityResult().
@@ -4255,6 +4278,8 @@
final void performCreate(Bundle icicle) {
onCreate(icicle);
+ mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
+ com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c0714e3..a8f08c2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -224,6 +224,11 @@
boolean startsNotResumed;
boolean isForward;
+ int pendingConfigChanges;
+ boolean onlyLocalRequest;
+
+ View mPendingRemoveWindow;
+ WindowManager mPendingRemoveWindowManager;
ActivityClientRecord() {
parent = null;
@@ -444,19 +449,8 @@
public final void scheduleRelaunchActivity(IBinder token,
List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
int configChanges, boolean notResumed, Configuration config) {
- ActivityClientRecord r = new ActivityClientRecord();
-
- r.token = token;
- r.pendingResults = pendingResults;
- r.pendingIntents = pendingNewIntents;
- r.startsNotResumed = notResumed;
- r.createdConfig = config;
-
- synchronized (mPackages) {
- mRelaunchingActivities.add(r);
- }
-
- queueOrSendMessage(H.RELAUNCH_ACTIVITY, r, configChanges);
+ requestRelaunchActivity(token, pendingResults, pendingNewIntents,
+ configChanges, notResumed, config, true);
}
public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
@@ -981,7 +975,7 @@
} break;
case RELAUNCH_ACTIVITY: {
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
- handleRelaunchActivity(r, msg.arg1);
+ handleRelaunchActivity(r);
} break;
case PAUSE_ACTIVITY:
handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
@@ -2183,6 +2177,19 @@
return r;
}
+ final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
+ if (r.mPendingRemoveWindow != null) {
+ r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
+ IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
+ if (wtoken != null) {
+ WindowManagerImpl.getDefault().closeAll(wtoken,
+ r.activity.getClass().getName(), "Activity");
+ }
+ }
+ r.mPendingRemoveWindow = null;
+ r.mPendingRemoveWindowManager = null;
+ }
+
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
@@ -2235,6 +2242,9 @@
r.hideForNow = true;
}
+ // Get rid of anything left hanging around.
+ cleanUpPendingRemoveWindows(r);
+
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible
@@ -2267,11 +2277,14 @@
}
}
- r.nextIdle = mNewActivities;
- mNewActivities = r;
- if (localLOGV) Slog.v(
- TAG, "Scheduling idle handler for " + r);
- Looper.myQueue().addIdleHandler(new Idler());
+ if (!r.onlyLocalRequest) {
+ r.nextIdle = mNewActivities;
+ mNewActivities = r;
+ if (localLOGV) Slog.v(
+ TAG, "Scheduling idle handler for " + r);
+ Looper.myQueue().addIdleHandler(new Idler());
+ }
+ r.onlyLocalRequest = false;
} else {
// If an exception was thrown when trying to resume, then
@@ -2728,6 +2741,7 @@
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
if (r != null) {
+ cleanUpPendingRemoveWindows(r);
WindowManager wm = r.activity.getWindowManager();
View v = r.activity.mDecor;
if (v != null) {
@@ -2736,16 +2750,31 @@
}
IBinder wtoken = v.getWindowToken();
if (r.activity.mWindowAdded) {
- wm.removeViewImmediate(v);
+ if (r.onlyLocalRequest) {
+ // Hold off on removing this until the new activity's
+ // window is being added.
+ r.mPendingRemoveWindow = v;
+ r.mPendingRemoveWindowManager = wm;
+ } else {
+ wm.removeViewImmediate(v);
+ }
}
- if (wtoken != null) {
+ if (wtoken != null && r.mPendingRemoveWindow == null) {
WindowManagerImpl.getDefault().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
}
r.activity.mDecor = null;
}
- WindowManagerImpl.getDefault().closeAll(token,
- r.activity.getClass().getName(), "Activity");
+ if (r.mPendingRemoveWindow == null) {
+ // If we are delaying the removal of the activity window, then
+ // we can't clean up all windows here. Note that we can't do
+ // so later either, which means any windows that aren't closed
+ // by the app will leak. Well we try to warning them a lot
+ // about leaking windows, because that is a bug, so if they are
+ // using this recreate facility then they get to live with leaks.
+ WindowManagerImpl.getDefault().closeAll(token,
+ r.activity.getClass().getName(), "Activity");
+ }
// Mocked out contexts won't be participating in the normal
// process lifecycle, but if we're running with a proper
@@ -2766,17 +2795,70 @@
}
}
- private final void handleRelaunchActivity(ActivityClientRecord tmp, int configChanges) {
+ public final void requestRelaunchActivity(IBinder token,
+ List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
+ int configChanges, boolean notResumed, Configuration config,
+ boolean fromServer) {
+ ActivityClientRecord target = null;
+
+ synchronized (mPackages) {
+ for (int i=0; i<mRelaunchingActivities.size(); i++) {
+ ActivityClientRecord r = mRelaunchingActivities.get(i);
+ if (r.token == token) {
+ target = r;
+ if (pendingResults != null) {
+ if (r.pendingResults != null) {
+ r.pendingResults.addAll(pendingResults);
+ } else {
+ r.pendingResults = pendingResults;
+ }
+ }
+ if (pendingNewIntents != null) {
+ if (r.pendingIntents != null) {
+ r.pendingIntents.addAll(pendingNewIntents);
+ } else {
+ r.pendingIntents = pendingNewIntents;
+ }
+ }
+ break;
+ }
+ }
+
+ if (target == null) {
+ target = new ActivityClientRecord();
+ target.token = token;
+ target.pendingResults = pendingResults;
+ target.pendingIntents = pendingNewIntents;
+ if (!fromServer) {
+ ActivityClientRecord existing = mActivities.get(token);
+ if (existing != null) {
+ target.startsNotResumed = existing.paused;
+ }
+ target.onlyLocalRequest = true;
+ }
+ mRelaunchingActivities.add(target);
+ queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
+ }
+
+ if (fromServer) {
+ target.startsNotResumed = notResumed;
+ target.onlyLocalRequest = false;
+ }
+ if (config != null) {
+ target.createdConfig = config;
+ }
+ target.pendingConfigChanges |= configChanges;
+ }
+ }
+
+ private final void handleRelaunchActivity(ActivityClientRecord tmp) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
Configuration changedConfig = null;
+ int configChanges = 0;
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
- + tmp.token + " with configChanges=0x"
- + Integer.toHexString(configChanges));
-
// First: make sure we have the most recent configuration and most
// recent version of the activity, or skip it if some previous call
// had taken a more recent version.
@@ -2788,6 +2870,7 @@
ActivityClientRecord r = mRelaunchingActivities.get(i);
if (r.token == token) {
tmp = r;
+ configChanges |= tmp.pendingConfigChanges;
mRelaunchingActivities.remove(i);
i--;
N--;
@@ -2799,6 +2882,10 @@
return;
}
+ if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
+ + tmp.token + " with configChanges=0x"
+ + Integer.toHexString(configChanges));
+
if (mPendingConfiguration != null) {
changedConfig = mPendingConfiguration;
mPendingConfiguration = null;
@@ -2834,6 +2921,7 @@
}
r.activity.mConfigChangeFlags |= configChanges;
+ r.onlyLocalRequest = tmp.onlyLocalRequest;
Intent currentIntent = r.activity.mIntent;
Bundle savedState = null;
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 64a4d7a..f90fc59 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -735,6 +735,9 @@
* @see Activity#onMenuOpened(int, Menu)
*/
public boolean onMenuOpened(int featureId, Menu menu) {
+ if (featureId == Window.FEATURE_ACTION_BAR) {
+ mActionBar.dispatchMenuVisibilityChanged(true);
+ }
return true;
}
@@ -749,6 +752,9 @@
* @see Activity#onPanelClosed(int, Menu)
*/
public void onPanelClosed(int featureId, Menu menu) {
+ if (featureId == Window.FEATURE_ACTION_BAR) {
+ mActionBar.dispatchMenuVisibilityChanged(false);
+ }
}
/**
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index f3b2c81..fe4b900 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1021,6 +1021,9 @@
private static final String KEY_ZOOM_SUPPORTED = "zoom-supported";
private static final String KEY_SMOOTH_ZOOM_SUPPORTED = "smooth-zoom-supported";
private static final String KEY_FOCUS_DISTANCES = "focus-distances";
+ private static final String KEY_VIDEO_SIZE = "video-size";
+ private static final String KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO =
+ "preferred-preview-size-for-video";
// Parameter key suffix for supported values.
private static final String SUPPORTED_VALUES_SUFFIX = "-values";
@@ -1398,7 +1401,7 @@
/**
* Returns the dimensions setting for preview pictures.
*
- * @return a Size object with the height and width setting
+ * @return a Size object with the width and height setting
* for the preview picture
*/
public Size getPreviewSize() {
@@ -1418,6 +1421,46 @@
}
/**
+ * Gets the supported video frame sizes that can be used by
+ * MediaRecorder.
+ *
+ * If the returned list is not null, the returned list will contain at
+ * least one Size and one of the sizes in the returned list must be
+ * passed to MediaRecorder.setVideoSize() for camcorder application if
+ * camera is used as the video source. In this case, the size of the
+ * preview can be different from the resolution of the recorded video
+ * during video recording.
+ *
+ * @return a list of Size object if camera has separate preview and
+ * video output; otherwise, null is returned.
+ * @see #getPreferredPreviewSizeForVideo()
+ */
+ public List<Size> getSupportedVideoSizes() {
+ String str = get(KEY_VIDEO_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitSize(str);
+ }
+
+ /**
+ * Returns the preferred or recommended preview size (width and height)
+ * in pixels for video recording. Camcorder applications should
+ * set the preview size to a value that is not larger than the
+ * preferred preview size. In other words, the product of the width
+ * and height of the preview size should not be larger than that of
+ * the preferred preview size. In addition, we recommend to choose a
+ * preview size that has the same aspect ratio as the resolution of
+ * video to be recorded.
+ *
+ * @return the preferred preview size (width and height) in pixels for
+ * video recording if getSupportedVideoSizes() does not return
+ * null; otherwise, null is returned.
+ * @see #getSupportedVideoSizes()
+ */
+ public Size getPreferredPreviewSizeForVideo() {
+ String pair = get(KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
+ return strToSize(pair);
+ }
+
+ /**
* Sets the dimensions for EXIF thumbnail in Jpeg picture. If
* applications set both width and height to 0, EXIF will not contain
* thumbnail.
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 683e603..b2b8c5a 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -51,7 +51,14 @@
"android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED";
/**
- * The permission to directly access the download manager's cache directory
+ * The permission to access the all the downloads in the manager.
+ */
+ public static final String PERMISSION_ACCESS_ALL =
+ "android.permission.ACCESS_ALL_DOWNLOADS";
+
+ /**
+ * The permission to directly access the download manager's cache
+ * directory
*/
public static final String PERMISSION_CACHE = "android.permission.ACCESS_CACHE_FILESYSTEM";
diff --git a/core/java/android/provider/Ptp.java b/core/java/android/provider/Ptp.java
index 2c54370..0f0919e 100644
--- a/core/java/android/provider/Ptp.java
+++ b/core/java/android/provider/Ptp.java
@@ -20,10 +20,13 @@
import android.net.Uri;
import android.util.Log;
-
/**
* The PTP provider supports accessing content on PTP devices.
- * @hide
+ * Currently the provider supports:
+ * - enumerating the storage units, files and directories on PTP devices
+ * - deleting files and directories on PTP devices
+ * - importing a file from PTP device into the host device's storage
+ * and adding it to the media provider
*/
public final class Ptp
{
@@ -36,6 +39,8 @@
/**
* Contains list of all PTP devices
+ * The BaseColumns._ID column contains a hardware specific identifier for the attached
+ * USB device, and is not guaranteed to be persistent across USB disconnects.
*/
public static final class Device implements BaseColumns {
@@ -59,7 +64,8 @@
}
/**
- * Contains list of storage units for an PTP device
+ * Contains list of storage units for an PTP device.
+ * The BaseColumns._ID column contains the PTP StorageID for the storage unit.
*/
public static final class Storage implements BaseColumns {
@@ -85,7 +91,10 @@
}
/**
- * Contains list of objects on an PTP device
+ * Contains list of objects on a PTP device.
+ * The columns in this table correspond directly to the ObjectInfo dataset
+ * described in the PTP specification (PIMA 15740:2000).
+ * The BaseColumns._ID column contains the object's PTP ObjectHandle.
*/
public static final class Object implements BaseColumns {
@@ -135,14 +144,14 @@
public static final String STORAGE_ID = "storage_id";
/**
- * The object's format. Can be one of the FORMAT_* symbols below,
- * or any of the valid PTP object formats as defined in the PTP specification.
+ * The object's format. Can be any of the valid PTP object formats
+ * as defined in the PTP specification.
* <P>Type: INTEGER</P>
*/
public static final String FORMAT = "format";
/**
- * The protection status of the object. See the PROTECTION_STATUS_*symbols below.
+ * The protection status of the object.
* <P>Type: INTEGER</P>
*/
public static final String PROTECTION_STATUS = "protection_status";
@@ -154,8 +163,8 @@
public static final String SIZE = "size";
/**
- * The object's thumbnail format. Can be one of the FORMAT_* symbols below,
- * or any of the valid PTP object formats as defined in the PTP specification.
+ * The object's thumbnail format. Can be any of the valid PTP object formats
+ * as defined in the PTP specification.
* <P>Type: INTEGER</P>
*/
public static final String THUMB_FORMAT = "thumb_format";
@@ -211,7 +220,6 @@
/**
* The association type for a container object.
- * For folders this is typically {@link #ASSOCIATION_TYPE_GENERIC_FOLDER}
* <P>Type: INTEGER</P>
*/
public static final String ASSOCIATION_TYPE = "association_type";
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 07e87d6..6634f00 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -29,6 +29,7 @@
float mX, mY;
ClipDescription mClipDescription;
ClipData mClipData;
+ Object mLocalState;
boolean mDragResult;
private DragEvent mNext;
@@ -139,11 +140,11 @@
}
static DragEvent obtain() {
- return DragEvent.obtain(0, 0f, 0f, null, null, false);
+ return DragEvent.obtain(0, 0f, 0f, null, null, null, false);
}
/** @hide */
- public static DragEvent obtain(int action, float x, float y,
+ public static DragEvent obtain(int action, float x, float y, Object localState,
ClipDescription description, ClipData data, boolean result) {
final DragEvent ev;
synchronized (gRecyclerLock) {
@@ -167,7 +168,7 @@
/** @hide */
public static DragEvent obtain(DragEvent source) {
- return obtain(source.mAction, source.mX, source.mY,
+ return obtain(source.mAction, source.mX, source.mY, source.mLocalState,
source.mClipDescription, source.mClipData, source.mDragResult);
}
@@ -218,6 +219,15 @@
}
/**
+ * Provides the local state object passed as the {@code myLocalState} parameter to
+ * View.startDrag(). The object will always be null here if the application receiving
+ * the DragEvent is not the one that started the drag.
+ */
+ public Object getLocalState() {
+ return mLocalState;
+ }
+
+ /**
* Provides an indication of whether the drag operation concluded successfully.
* This method is only available on ACTION_DRAG_ENDED events.
* @return {@code true} if the drag operation ended with an accepted drop; {@code false}
@@ -249,6 +259,7 @@
mClipData = null;
mClipDescription = null;
+ mLocalState = null;
synchronized (gRecyclerLock) {
if (gRecyclerUsed < MAX_RECYCLED) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f135fcc..6114800 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6430,12 +6430,6 @@
}
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
- if (p != null && ai != null && ai.mHardwareAccelerated) {
- // fast-track for GL-enabled applications; just invalidate the whole hierarchy
- // with a null dirty rect, which tells the ViewRoot to redraw everything
- p.invalidateChild(this, null);
- return;
- }
if (p != null && ai != null) {
final Rect r = ai.mTmpInvalRect;
@@ -10081,9 +10075,23 @@
* onProvideThumbnailMetrics() and onDrawThumbnail() methods happen, then the drag
* operation is handed over to the OS.
* !!! TODO: real docs
+ *
+ * @param data !!! TODO
+ * @param thumbBuilder !!! TODO
+ * @param myWindowOnly When {@code true}, indicates that the drag operation should be
+ * restricted to the calling application. In this case only the calling application
+ * will see any DragEvents related to this drag operation.
+ * @param myLocalState An arbitrary object that will be passed as part of every DragEvent
+ * delivered to the calling application during the course of the current drag operation.
+ * This object is private to the application that called startDrag(), and is not
+ * visible to other applications. It provides a lightweight way for the application to
+ * propagate information from the initiator to the recipient of a drag within its own
+ * application; for example, to help disambiguate between 'copy' and 'move' semantics.
+ * @return {@code true} if the drag operation was initiated successfully; {@code false} if
+ * an error prevented the drag from taking place.
*/
public final boolean startDrag(ClipData data, DragThumbnailBuilder thumbBuilder,
- boolean myWindowOnly) {
+ boolean myWindowOnly, Object myLocalState) {
if (ViewDebug.DEBUG_DRAG) {
Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " local=" + myWindowOnly);
}
@@ -10117,8 +10125,13 @@
surface.unlockCanvasAndPost(canvas);
}
+ final ViewRoot root = getViewRoot();
+
+ // Cache the local state object for delivery with DragEvents
+ root.setLocalDragState(myLocalState);
+
// repurpose 'thumbSize' for the last touch point
- getViewRoot().getLastTouchPoint(thumbSize);
+ root.getLastTouchPoint(thumbSize);
okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
(float) thumbSize.x, (float) thumbSize.y,
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index bb85894..6b41ce5 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -166,7 +166,7 @@
/**
* Max distance to overfling for edge effects
*/
- private static final int OVERFLING_DISTANCE = 4;
+ private static final int OVERFLING_DISTANCE = 12;
private final int mEdgeSlop;
private final int mFadingEdgeLength;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 77083a9..5f3184d 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -228,6 +228,7 @@
/* Drag/drop */
ClipDescription mDragDescription;
View mCurrentDragView;
+ Object mLocalDragState;
final PointF mDragPoint = new PointF();
final PointF mLastTouchPoint = new PointF();
@@ -585,6 +586,9 @@
dirty.inset(-1, -1);
}
}
+ if (!mDirty.isEmpty()) {
+ mAttachInfo.mIgnoreDirtyState = true;
+ }
mDirty.union(dirty);
if (!mWillDrawSoon) {
scheduleTraversals();
@@ -2680,6 +2684,10 @@
}
/* drag/drop */
+ void setLocalDragState(Object obj) {
+ mLocalDragState = obj;
+ }
+
private void handleDragEvent(DragEvent event) {
// From the root, only drag start/end/location are dispatched. entered/exited
// are determined and dispatched by the viewgroup hierarchy, who then report
@@ -2738,7 +2746,7 @@
}
}
- // Report the drop result if necessary
+ // Report the drop result when we're done
if (what == DragEvent.ACTION_DROP) {
try {
Log.i(TAG, "Reporting drop result: " + result);
@@ -2747,6 +2755,12 @@
Log.e(TAG, "Unable to report drop result");
}
}
+
+ // When the drag operation ends, release any local state object
+ // that may have been in use
+ if (what == DragEvent.ACTION_DRAG_ENDED) {
+ setLocalDragState(null);
+ }
}
}
event.recycle();
@@ -3063,6 +3077,7 @@
} else {
what = DISPATCH_DRAG_EVENT;
}
+ event.mLocalState = mLocalDragState; // only present when this app called startDrag()
Message msg = obtainMessage(what, event);
sendMessage(msg);
}
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index 27043e0..641604e 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -43,7 +43,6 @@
private Resources mResources;
private boolean mMatchesFound;
private int mNumberOfMatches;
- private View mTitleBar;
private ActionMode mActionMode;
FindActionModeCallback(Context context) {
@@ -62,8 +61,6 @@
mResources = context.getResources();
}
- void setTitleBar(View v) { mTitleBar = v; }
-
void finish() {
mActionMode.finish();
}
@@ -174,7 +171,6 @@
@Override
public void onDestroyActionMode(ActionMode mode) {
- if (mTitleBar != null) mWebView.setEmbeddedTitleBar(mTitleBar);
mWebView.notifyFindDialogDismissed();
mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b8ccf45..be475ca 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -314,6 +314,17 @@
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener {
+ private class InnerGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
+ public void onGlobalLayout() {
+ if (isShown()) {
+ setGLRectViewport();
+ }
+ }
+ }
+
+ // The listener to capture global layout change event.
+ private InnerGlobalLayoutListener mListener = null;
+
// if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
// the screen all-the-time. Good for profiling our drawing code
static private final boolean AUTO_REDRAW_HACK = false;
@@ -2253,13 +2264,6 @@
* @hide
*/
public void setEmbeddedTitleBar(View v) {
- if (null == v) {
- // If one of our callbacks is holding onto the titlebar to replace
- // it when its ActionMode ends, remove it.
- if (mFindCallback != null) {
- mFindCallback.setTitleBar(null);
- }
- }
if (mTitleBar == v) return;
if (mTitleBar != null) {
removeView(mTitleBar);
@@ -2894,11 +2898,6 @@
setFindIsUp(true);
mFindCallback.setWebView(this);
View titleBar = mTitleBar;
- // We do not want to show the embedded title bar during find or
- // select, but keep track of it so that it can be replaced when the
- // mode is exited.
- setEmbeddedTitleBar(null);
- mFindCallback.setTitleBar(titleBar);
startActionMode(mFindCallback);
if (text == null) {
text = mLastFind;
@@ -4701,6 +4700,11 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (hasWindowFocus()) setActive(true);
+ final ViewTreeObserver treeObserver = getViewTreeObserver();
+ if (treeObserver != null && mListener == null) {
+ mListener = new InnerGlobalLayoutListener();
+ treeObserver.addOnGlobalLayoutListener(mListener);
+ }
}
@Override
@@ -4708,6 +4712,13 @@
clearHelpers();
mZoomManager.dismissZoomPicker();
if (hasWindowFocus()) setActive(false);
+
+ final ViewTreeObserver treeObserver = getViewTreeObserver();
+ if (treeObserver != null && mListener != null) {
+ treeObserver.removeGlobalOnLayoutListener(mListener);
+ mListener = null;
+ }
+
super.onDetachedFromWindow();
}
@@ -4848,13 +4859,19 @@
}
void setGLRectViewport() {
- View window = getRootView();
- int[] location = new int[2];
- getLocationInWindow(location);
- mGLRectViewport = new Rect(location[0], window.getHeight()
- - (location[1] + getHeight()),
- location[0] + getWidth(),
- window.getHeight() - location[1]);
+ // Use the getGlobalVisibleRect() to get the intersection among the parents
+ Rect webViewRect = new Rect();
+ boolean visible = getGlobalVisibleRect(webViewRect);
+
+ // Then need to invert the Y axis, just for GL
+ View rootView = getRootView();
+ int rootViewHeight = rootView.getHeight();
+ int savedWebViewBottom = webViewRect.bottom;
+ webViewRect.bottom = rootViewHeight - webViewRect.top;
+ webViewRect.top = rootViewHeight - savedWebViewBottom;
+
+ // Store the viewport
+ mGLRectViewport = webViewRect;
}
/**
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 1e5489a..99b181f 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -20,6 +20,8 @@
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 android.view.View;
@@ -57,6 +59,23 @@
public static final int VERTICAL = 1;
/**
+ * Don't show any dividers.
+ */
+ public static final int SHOW_DIVIDER_NONE = 0;
+ /**
+ * Show a divider at the beginning of the group.
+ */
+ public static final int SHOW_DIVIDER_BEGINNING = 1;
+ /**
+ * Show dividers between each item in the group.
+ */
+ public static final int SHOW_DIVIDER_MIDDLE = 2;
+ /**
+ * Show a divider at the end of the group.
+ */
+ public static final int SHOW_DIVIDER_END = 4;
+
+ /**
* Whether the children of this layout are baseline aligned. Only applicable
* if {@link #mOrientation} is horizontal.
*/
@@ -119,6 +138,12 @@
private static final int INDEX_BOTTOM = 2;
private static final int INDEX_FILL = 3;
+ private Drawable mDivider;
+ private int mDividerWidth;
+ private int mDividerHeight;
+ private int mShowDividers;
+ private int mDividerPadding;
+
public LinearLayout(Context context) {
super(context);
}
@@ -155,10 +180,158 @@
mUseLargestChild = a.getBoolean(R.styleable.LinearLayout_measureWithLargestChild, false);
+ setDividerDrawable(a.getDrawable(R.styleable.LinearLayout_divider));
+ mShowDividers = a.getInt(R.styleable.LinearLayout_showDividers, SHOW_DIVIDER_NONE);
+ mDividerPadding = a.getDimensionPixelSize(R.styleable.LinearLayout_dividerPadding, 0);
+
a.recycle();
}
/**
+ * Set how dividers should be shown between items in this layout
+ *
+ * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING},
+ * {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
+ * or {@link #SHOW_DIVIDER_NONE} to show no dividers.
+ */
+ public void setShowDividers(int showDividers) {
+ if (showDividers != mShowDividers) {
+ requestLayout();
+ }
+ mShowDividers = showDividers;
+ }
+
+ /**
+ * @return A flag set indicating how dividers should be shown around items.
+ * @see #setShowDividers(int)
+ */
+ public int getShowDividers() {
+ return mShowDividers;
+ }
+
+ /**
+ * Set a drawable to be used as a divider between items.
+ * @param divider Drawable that will divide each item.
+ * @see #setShowDividers(int)
+ */
+ public void setDividerDrawable(Drawable divider) {
+ if (divider == mDivider) {
+ return;
+ }
+ mDivider = divider;
+ if (divider != null) {
+ mDividerWidth = divider.getIntrinsicWidth();
+ mDividerHeight = divider.getIntrinsicHeight();
+ } else {
+ mDividerWidth = 0;
+ mDividerHeight = 0;
+ }
+ setWillNotDraw(divider == null);
+ requestLayout();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mDivider == null) {
+ return;
+ }
+
+ if (mOrientation == VERTICAL) {
+ drawDividersVertical(canvas);
+ } else {
+ drawDividersHorizontal(canvas);
+ }
+ }
+
+ void drawDividersVertical(Canvas canvas) {
+ final boolean showDividerBeginning =
+ (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+ final boolean showDividerEnd =
+ (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END;
+
+ final int count = getVirtualChildCount();
+ int top = getPaddingTop();
+ boolean firstVisible = true;
+ for (int i = 0; i < count; i++) {
+ final View child = getVirtualChildAt(i);
+
+ if (child == null) {
+ top += measureNullChild(i);
+ } else if (child.getVisibility() != GONE) {
+ if (firstVisible) {
+ firstVisible = false;
+ if (showDividerBeginning) {
+ drawHorizontalDivider(canvas, top);
+ top += mDividerHeight;
+ }
+ } else if (showDividerMiddle) {
+ drawHorizontalDivider(canvas, top);
+ top += mDividerHeight;
+ }
+
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ top += lp.topMargin + child.getHeight() + lp.bottomMargin;
+ }
+ }
+
+ if (showDividerEnd) {
+ drawHorizontalDivider(canvas, top);
+ }
+ }
+
+ void drawDividersHorizontal(Canvas canvas) {
+ final boolean showDividerBeginning =
+ (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+ final boolean showDividerEnd =
+ (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END;
+
+ final int count = getVirtualChildCount();
+ int left = getPaddingLeft();
+ boolean firstVisible = true;
+ for (int i = 0; i < count; i++) {
+ final View child = getVirtualChildAt(i);
+
+ if (child == null) {
+ left += measureNullChild(i);
+ } else if (child.getVisibility() != GONE) {
+ if (firstVisible) {
+ firstVisible = false;
+ if (showDividerBeginning) {
+ drawVerticalDivider(canvas, left);
+ left += mDividerWidth;
+ }
+ } else if (showDividerMiddle) {
+ drawVerticalDivider(canvas, left);
+ left += mDividerWidth;
+ }
+
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ left += lp.leftMargin + child.getWidth() + lp.rightMargin;
+ }
+ }
+
+ if (showDividerEnd) {
+ drawVerticalDivider(canvas, left);
+ }
+ }
+
+ void drawHorizontalDivider(Canvas canvas, int top) {
+ mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
+ getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
+ mDivider.draw(canvas);
+ }
+
+ void drawVerticalDivider(Canvas canvas, int left) {
+ mDivider.setBounds(left, getPaddingTop() + mDividerPadding,
+ left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);
+ mDivider.draw(canvas);
+ }
+
+ /**
* <p>Indicates whether widgets contained within this layout are aligned
* on their baseline or not.</p>
*
@@ -380,7 +553,14 @@
int largestChildHeight = Integer.MIN_VALUE;
+ // A divider at the end will change how much space views can consume.
+ final boolean showDividerBeginning =
+ (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+
// See how tall everyone is. Also remember max width.
+ boolean firstVisible = true;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
@@ -394,6 +574,15 @@
continue;
}
+ if (firstVisible) {
+ firstVisible = false;
+ if (showDividerBeginning) {
+ mTotalLength += mDividerHeight;
+ }
+ } else if (showDividerMiddle) {
+ mTotalLength += mDividerHeight;
+ }
+
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;
@@ -486,6 +675,10 @@
i += getChildrenSkipCount(child, i);
}
+ if (mTotalLength > 0 && (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END) {
+ mTotalLength += mDividerHeight;
+ }
+
if (useLargestChild && heightMode == MeasureSpec.AT_MOST) {
mTotalLength = 0;
@@ -679,7 +872,14 @@
int largestChildWidth = Integer.MIN_VALUE;
+ // A divider at the end will change how much space views can consume.
+ final boolean showDividerBeginning =
+ (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+
// See how wide everyone is. Also remember max height.
+ boolean firstVisible = true;
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
@@ -693,6 +893,15 @@
continue;
}
+ if (firstVisible) {
+ firstVisible = false;
+ if (showDividerBeginning) {
+ mTotalLength += mDividerWidth;
+ }
+ } else if (showDividerMiddle) {
+ mTotalLength += mDividerWidth;
+ }
+
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
child.getLayoutParams();
@@ -803,6 +1012,10 @@
i += getChildrenSkipCount(child, i);
}
+ if (mTotalLength > 0 && (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END) {
+ mTotalLength += mDividerWidth;
+ }
+
// Check mMaxAscent[INDEX_TOP] first because it maps to Gravity.TOP,
// the most common case
if (maxAscent[INDEX_TOP] != -1 ||
@@ -1127,7 +1340,14 @@
}
}
-
+
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+
+ if ((mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING) {
+ childTop += mDividerHeight;
+ }
+
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
if (child == null) {
@@ -1162,12 +1382,15 @@
break;
}
-
childTop += lp.topMargin;
setChildFrame(child, childLeft, childTop + getLocationOffset(child),
childWidth, childHeight);
childTop += childHeight + lp.bottomMargin + getNextLocationOffset(child);
+ if (showDividerMiddle) {
+ childTop += mDividerHeight;
+ }
+
i += getChildrenSkipCount(child, i);
}
}
@@ -1216,7 +1439,14 @@
childLeft += ((mRight - mLeft) - mTotalLength) / 2;
break;
}
- }
+ }
+
+ final boolean showDividerMiddle =
+ (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
+
+ if ((mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING) {
+ childLeft += mDividerWidth;
+ }
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
@@ -1282,6 +1512,10 @@
childLeft += childWidth + lp.rightMargin +
getNextLocationOffset(child);
+ if (showDividerMiddle) {
+ childLeft += mDividerWidth;
+ }
+
i += getChildrenSkipCount(child, i);
}
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index fd4f950..c0721bc 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3196,7 +3196,8 @@
}
mDivider = divider;
mDividerIsOpaque = divider == null || divider.getOpacity() == PixelFormat.OPAQUE;
- requestLayoutIfNecessary();
+ requestLayout();
+ invalidate();
}
/**
@@ -3214,7 +3215,8 @@
*/
public void setDividerHeight(int height) {
mDividerHeight = height;
- requestLayoutIfNecessary();
+ requestLayout();
+ invalidate();
}
/**
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index cd81e31..b9e59d6 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -17,9 +17,12 @@
package android.widget;
import android.content.Context;
-import android.graphics.Interpolator;
+import android.hardware.SensorManager;
+import android.util.FloatMath;
+import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
/**
* This class encapsulates scrolling with the ability to overshoot the bounds
@@ -27,65 +30,51 @@
* {@link android.widget.Scroller} in most cases.
*/
public class OverScroller {
- int mMode;
+ private int mMode;
- private final MagneticOverScroller mScrollerX;
- private final MagneticOverScroller mScrollerY;
+ private final SplineOverScroller mScrollerX;
+ private final SplineOverScroller mScrollerY;
- private float mDeceleration;
- private final float mPpi;
+ private final Interpolator mInterpolator;
+
private final boolean mFlywheel;
- private static float DECELERATION_RATE = (float) (Math.log(0.75) / Math.log(0.9));
- private static float ALPHA = 800; // pixels / seconds
- private static float START_TENSION = 0.4f; // Tension at start: (0.4 * total T, 1.0 * Distance)
- private static float END_TENSION = 1.0f - START_TENSION;
- private static final int NB_SAMPLES = 100;
- private static final float[] SPLINE_POSITION = new float[NB_SAMPLES + 1];
- private static final float[] SPLINE_TIME = new float[NB_SAMPLES + 1];
-
private static final int DEFAULT_DURATION = 250;
private static final int SCROLL_MODE = 0;
private static final int FLING_MODE = 1;
- static {
- float x_min = 0.0f;
- float y_min = 0.0f;
- for (int i = 0; i < NB_SAMPLES; i++) {
- final float alpha = (float) i / NB_SAMPLES;
- {
- float x_max = 1.0f;
- float x, tx, coef;
- while (true) {
- x = x_min + (x_max - x_min) / 2.0f;
- coef = 3.0f * x * (1.0f - x);
- tx = coef * ((1.0f - x) * START_TENSION + x * END_TENSION) + x * x * x;
- if (Math.abs(tx - alpha) < 1E-5) break;
- if (tx > alpha) x_max = x;
- else x_min = x;
- }
- SPLINE_POSITION[i] = coef + x * x * x;
- }
-
- {
- float y_max = 1.0f;
- float y, dy, coef;
- while (true) {
- y = y_min + (y_max - y_min) / 2.0f;
- coef = 3.0f * y * (1.0f - y);
- dy = coef + y * y * y;
- if (Math.abs(dy - alpha) < 1E-5) break;
- if (dy > alpha) y_max = y;
- else y_min = y;
- }
- SPLINE_TIME[i] = coef * ((1.0f - y) * START_TENSION + y * END_TENSION) + y * y * y;
- }
- }
- SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
+ /**
+ * Creates an OverScroller with a viscous fluid scroll interpolator.
+ * @param context
+ */
+ public OverScroller(Context context) {
+ this(context, null);
}
- public OverScroller(Context context) {
- this(context, null, 0.f, 0.f, true);
+ /**
+ * Creates an OverScroller with default edge bounce coefficients and flywheel enabled.
+ * @param context The context of this application.
+ * @param interpolator The scroll interpolator. If null, a default (viscous) interpolator will
+ * be used.
+ */
+ public OverScroller(Context context, Interpolator interpolator) {
+ this(context, interpolator, SplineOverScroller.DEFAULT_BOUNCE_COEFFICIENT,
+ SplineOverScroller.DEFAULT_BOUNCE_COEFFICIENT);
+ }
+
+ /**
+ * Creates an OverScroller with flywheel enabled.
+ * @param context The context of this application.
+ * @param interpolator The scroll interpolator. If null, a default (viscous) interpolator will
+ * be used.
+ * @param bounceCoefficientX A value between 0 and 1 that will determine the proportion of the
+ * velocity which is preserved in the bounce when the horizontal edge is reached. A null value
+ * means no bounce.
+ * @param bounceCoefficientY Same as bounceCoefficientX but for the vertical direction.
+ */
+ public OverScroller(Context context, Interpolator interpolator,
+ float bounceCoefficientX, float bounceCoefficientY) {
+ this(context, interpolator, bounceCoefficientX, bounceCoefficientY, true);
}
/**
@@ -97,20 +86,21 @@
* velocity which is preserved in the bounce when the horizontal edge is reached. A null value
* means no bounce.
* @param bounceCoefficientY Same as bounceCoefficientX but for the vertical direction.
+ * @param flywheel If true, successive fling motions will keep on increasing scroll speed.
*/
public OverScroller(Context context, Interpolator interpolator,
float bounceCoefficientX, float bounceCoefficientY, boolean flywheel) {
+ mInterpolator = interpolator;
mFlywheel = flywheel;
- mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
- mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
- mScrollerX = new MagneticOverScroller();
- mScrollerY = new MagneticOverScroller();
+ mScrollerX = new SplineOverScroller();
+ mScrollerY = new SplineOverScroller();
+
+ SplineOverScroller.initFromContext(context);
mScrollerX.setBounceCoefficient(bounceCoefficientX);
mScrollerY.setBounceCoefficient(bounceCoefficientY);
}
-
/**
* The amount of friction applied to flings. The default value
* is {@link ViewConfiguration#getScrollFriction}.
@@ -119,14 +109,8 @@
* friction.
*/
public final void setFriction(float friction) {
- mDeceleration = computeDeceleration(friction);
- }
-
- private float computeDeceleration(float friction) {
- return 9.81f // g (m/s^2)
- * 39.37f // inch/meter
- * mPpi // pixels per inch
- * friction;
+ mScrollerX.setFriction(friction);
+ mScrollerY.setFriction(friction);
}
/**
@@ -178,7 +162,7 @@
public float getCurrVelocity() {
float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity;
squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity;
- return (float) Math.sqrt(squaredNorm);
+ return FloatMath.sqrt(squaredNorm);
}
/**
@@ -307,7 +291,11 @@
if (elapsedTime < duration) {
float q = (float) (elapsedTime) / duration;
- q = Scroller.viscousFluid(q);
+ if (mInterpolator == null) {
+ q = Scroller.viscousFluid(q);
+ } else {
+ q = mInterpolator.getInterpolation(q);
+ }
mScrollerX.updateScroll(q);
mScrollerY.updateScroll(q);
@@ -496,9 +484,9 @@
*/
public boolean isOverScrolled() {
return ((!mScrollerX.mFinished &&
- mScrollerX.mState != MagneticOverScroller.TO_EDGE) ||
+ mScrollerX.mState != SplineOverScroller.TO_EDGE) ||
(!mScrollerY.mFinished &&
- mScrollerY.mState != MagneticOverScroller.TO_EDGE));
+ mScrollerY.mState != SplineOverScroller.TO_EDGE));
}
/**
@@ -536,60 +524,126 @@
Math.signum(yvel) == Math.signum(dy);
}
- class MagneticOverScroller {
+ static class SplineOverScroller {
// Initial position
- int mStart;
+ private int mStart;
// Current position
- int mCurrentPosition;
+ private int mCurrentPosition;
// Final position
- int mFinal;
+ private int mFinal;
// Initial velocity
- int mVelocity;
+ private int mVelocity;
// Current velocity
- float mCurrVelocity;
+ private float mCurrVelocity;
// Constant current deceleration
- float mDeceleration;
+ private float mDeceleration;
// Animation starting time, in system milliseconds
- long mStartTime;
+ private long mStartTime;
// Animation duration, in milliseconds
- int mDuration;
+ private int mDuration;
// Duration to complete spline component of animation
- int mSplineDuration;
+ private int mSplineDuration;
// Distance to travel along spline animation
- int mSplineDistance;
+ private int mSplineDistance;
// Whether the animation is currently in progress
- boolean mFinished;
+ private boolean mFinished;
+
+ // The allowed overshot distance before boundary is reached.
+ private int mOver;
+
+ // Fling friction
+ private float mFlingFriction = ViewConfiguration.getScrollFriction();
+
+ // Proportion of velocity preserved at the end of a bounce animation.
+ private float mBounceCoefficient = DEFAULT_BOUNCE_COEFFICIENT;
+
+ // Current state of the animation.
+ private int mState = TO_EDGE;
+
+ // Constant gravity value, used in the deceleration phase.
+ private static final float GRAVITY = 2000.0f;
+
+ // A device specific coefficient adjusted to physical values.
+ private static float PHYSICAL_COEF;
+
+ private static float DECELERATION_RATE = (float) (Math.log(0.75) / Math.log(0.9));
+ private static final float INFLEXION = 0.3f; // Tension lines cross at (INFLEXION, 1)
+ private static final float START_TENSION = 0.7f;
+ private static final float END_TENSION = 0.8f;
+ private static final float P1 = START_TENSION * INFLEXION;
+ private static final float P2 = 1.0f - END_TENSION * (1.0f - INFLEXION);
+
+ private static final int NB_SAMPLES = 100;
+ private static final float[] SPLINE_POSITION = new float[NB_SAMPLES + 1];
+ private static final float[] SPLINE_TIME = new float[NB_SAMPLES + 1];
private static final int TO_EDGE = 0;
private static final int TO_BOUNDARY = 1;
private static final int TO_BOUNCE = 2;
- private int mState = TO_EDGE;
-
- // The allowed overshot distance before boundary is reached.
- private int mOver;
-
// If the velocity is smaller than this value, no bounce is triggered
- // when the edge limits are reached (would result in a zero pixels
- // displacement anyway).
- private static final float MINIMUM_VELOCITY_FOR_BOUNCE = 140.0f; //Float.MAX_VALUE;//140.0f;
+ // when the edge limits are reached.
+ private static final float MINIMUM_VELOCITY_FOR_BOUNCE = Float.MAX_VALUE;//140.0f;
// Proportion of the velocity that is preserved when the edge is reached.
- private static final float DEFAULT_BOUNCE_COEFFICIENT = 0.36f;
+ private static final float DEFAULT_BOUNCE_COEFFICIENT = 0.16f;
- private float mBounceCoefficient = DEFAULT_BOUNCE_COEFFICIENT;
+ static {
+ float x_min = 0.0f;
+ float y_min = 0.0f;
+ for (int i = 0; i < NB_SAMPLES; i++) {
+ final float alpha = (float) i / NB_SAMPLES;
- MagneticOverScroller() {
+ float x_max = 1.0f;
+ float x, tx, coef;
+ while (true) {
+ x = x_min + (x_max - x_min) / 2.0f;
+ coef = 3.0f * x * (1.0f - x);
+ tx = coef * ((1.0f - x) * P1 + x * P2) + x * x * x;
+ if (Math.abs(tx - alpha) < 1E-5) break;
+ if (tx > alpha) x_max = x;
+ else x_min = x;
+ }
+ SPLINE_POSITION[i] = coef * ((1.0f - x) * START_TENSION + x) + x * x * x;
+
+ float y_max = 1.0f;
+ float y, dy;
+ while (true) {
+ y = y_min + (y_max - y_min) / 2.0f;
+ coef = 3.0f * y * (1.0f - y);
+ dy = coef * ((1.0f - y) * START_TENSION + y) + y * y * y;
+ if (Math.abs(dy - alpha) < 1E-5) break;
+ if (dy > alpha) y_max = y;
+ else y_min = y;
+ }
+ SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
+ }
+ SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
+ }
+
+ static void initFromContext(Context context) {
+ final float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
+ PHYSICAL_COEF = SensorManager.GRAVITY_EARTH // g (m/s^2)
+ * 39.37f // inch/meter
+ * ppi
+ * 0.84f; // look and feel tuning
+ }
+
+ void setFriction(float friction) {
+ mFlingFriction = friction;
+ }
+
+ SplineOverScroller() {
mFinished = true;
}
@@ -600,18 +654,18 @@
/*
* Get a signed deceleration that will reduce the velocity.
*/
- float getDeceleration(int velocity) {
- return velocity > 0 ? -OverScroller.this.mDeceleration : OverScroller.this.mDeceleration;
+ static private float getDeceleration(int velocity) {
+ return velocity > 0 ? -GRAVITY : GRAVITY;
}
/*
* Modifies mDuration to the duration it takes to get from start to newFinal using the
* spline interpolation. The previous duration was needed to get to oldFinal.
*/
- void adjustDuration(int start, int oldFinal, int newFinal) {
+ private void adjustDuration(int start, int oldFinal, int newFinal) {
final int oldDistance = oldFinal - start;
final int newDistance = newFinal - start;
- final float x = (float) Math.abs((float) newDistance / oldDistance);
+ final float x = Math.abs((float) newDistance / oldDistance);
final int index = (int) (NB_SAMPLES * x);
if (index < NB_SAMPLES) {
final float x_inf = (float) index / NB_SAMPLES;
@@ -619,7 +673,6 @@
final float t_inf = SPLINE_TIME[index];
final float t_sup = SPLINE_TIME[index + 1];
final float timeCoef = t_inf + (x - x_inf) / (x_sup - x_inf) * (t_sup - t_inf);
-
mDuration *= timeCoef;
}
}
@@ -696,7 +749,7 @@
mCurrVelocity = mVelocity = velocity;
mDuration = mSplineDuration = 0;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
- mStart = start;
+ mCurrentPosition = mStart = start;
if (start > max || start < min) {
startAfterEdge(start, min, max, velocity);
@@ -707,10 +760,8 @@
double totalDistance = 0.0;
if (velocity != 0) {
- final double l = Math.log(START_TENSION * Math.abs(velocity) / ALPHA);
- // Duration are expressed in milliseconds
- mDuration = mSplineDuration = (int) (1000.0 * Math.exp(l / (DECELERATION_RATE - 1.0)));
- totalDistance = (ALPHA * Math.exp(DECELERATION_RATE / (DECELERATION_RATE - 1.0) * l));
+ mDuration = mSplineDuration = getSplineFlingDuration(velocity);
+ totalDistance = getSplineFlingDistance(velocity);
}
mSplineDistance = (int) (totalDistance * Math.signum(velocity));
@@ -728,6 +779,23 @@
}
}
+ private double getSplineDeceleration(int velocity) {
+ return Math.log(INFLEXION * Math.abs(velocity) / (mFlingFriction * PHYSICAL_COEF));
+ }
+
+ private double getSplineFlingDistance(int velocity) {
+ final double l = getSplineDeceleration(velocity);
+ final double decelMinusOne = DECELERATION_RATE - 1.0;
+ return mFlingFriction * PHYSICAL_COEF * Math.exp(DECELERATION_RATE / decelMinusOne * l);
+ }
+
+ /* Returns the duration, expressed in milliseconds */
+ private int getSplineFlingDuration(int velocity) {
+ final double l = getSplineDeceleration(velocity);
+ final double decelMinusOne = DECELERATION_RATE - 1.0;
+ return (int) (1000.0 * Math.exp(l / decelMinusOne));
+ }
+
private void fitOnBounceCurve(int start, int end, int velocity) {
// Simulate a bounce that started from edge
final float durationToApex = - velocity / mDeceleration;
@@ -748,6 +816,7 @@
private void startAfterEdge(int start, int min, int max, int velocity) {
if (start > min && start < max) {
+ Log.e("OverScroller", "startAfterEdge called from a valid position");
mFinished = true;
return;
}
@@ -759,9 +828,7 @@
// Will result in a bounce or a to_boundary depending on velocity.
startBounceAfterEdge(start, edge, velocity);
} else {
- final double l = Math.log(START_TENSION * Math.abs(velocity) / ALPHA);
- final double totalDistance =
- (ALPHA * Math.exp(DECELERATION_RATE / (DECELERATION_RATE - 1.0) * l));
+ final double totalDistance = getSplineFlingDistance(velocity);
if (totalDistance > Math.abs(overDistance)) {
fling(start, velocity, positive ? min : start, positive ? start : max, mOver);
} else {
@@ -771,11 +838,13 @@
}
void notifyEdgeReached(int start, int end, int over) {
- mOver = over;
- mStartTime = AnimationUtils.currentAnimationTimeMillis();
- // We were in fling/scroll mode before: current velocity is such that distance to edge
- // is increasing. Ensures that startAfterEdge will not start a new fling.
- startAfterEdge(start, end, end, (int) mCurrVelocity);
+ if (mState == TO_EDGE) {
+ mOver = over;
+ mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ // We were in fling/scroll mode before: current velocity is such that distance to
+ // edge is increasing. Ensures that startAfterEdge will not start a new fling.
+ startAfterEdge(start, end, end, (int) mCurrVelocity);
+ }
}
private void onEdgeReached() {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index cfdcd32..ced8e9b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -89,6 +89,7 @@
import android.util.Log;
import android.util.TypedValue;
import android.view.ActionMode;
+import android.view.ActionMode.Callback;
import android.view.ContextMenu;
import android.view.DragEvent;
import android.view.Gravity;
@@ -314,6 +315,7 @@
Drawable mSelectHandleCenter;
private int mLastDownPositionX, mLastDownPositionY;
+ private Callback mCustomSelectionActionModeCallback;
/*
* Kick-start the font cache for the zygote process (to pay the cost of
@@ -6869,7 +6871,7 @@
}
if (mSelectAllOnFocus) {
- Selection.setSelection((Spannable) mText, 0, mText.length());
+ selectAll();
}
mTouchFocusSelected = true;
@@ -7401,10 +7403,8 @@
return false;
}
- if (mText.length() > 0 && hasSelection()) {
- if (mText instanceof Editable && mInput != null) {
- return true;
- }
+ if (mText.length() > 0 && hasSelection() && mText instanceof Editable && mInput != null) {
+ return true;
}
return false;
@@ -7524,13 +7524,17 @@
return (int) (range & 0x00000000FFFFFFFFL);
}
+ private void selectAll() {
+ Selection.setSelection((Spannable) mText, 0, mText.length());
+ }
+
private void selectCurrentWord() {
if (hasPasswordTransformationMethod()) {
// selectCurrentWord is not available on a password field and would return an
// arbitrary 10-charater selection around pressed position. Select all instead.
// Note that cut/copy menu entries are not available for passwords.
// This is however useful to delete or paste to replace the entire content.
- Selection.setSelection((Spannable) mText, 0, mText.length());
+ selectAll();
return;
}
@@ -7818,7 +7822,7 @@
final int end = getSelectionEnd();
CharSequence selectedText = mTransformed.subSequence(start, end);
ClipData data = ClipData.newPlainText(null, null, selectedText);
- startDrag(data, getTextThumbnailBuilder(selectedText), false);
+ startDrag(data, getTextThumbnailBuilder(selectedText), false, null);
mDragSourcePositions = packRangeInLong(start, end);
stopSelectionActionMode();
} else {
@@ -7862,16 +7866,36 @@
}
/**
- * Provides the callback used to start a selection action mode.
+ * If provided, this ActionMode.Callback will be used to create the ActionMode when text
+ * selection is initiated in this View.
*
- * @return A callback instance that will be used to start selection mode, or null if selection
- * mode is not available.
+ * The standard implementation populates the menu with a subset of Select All, Cut, Copy and
+ * Paste actions, depending on what this View supports.
+ *
+ * A custom implementation can add new entries in the default menu in its
+ * {@link ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The default actions
+ * can also be removed from the menu using {@link Menu#removeItem(int)} and passing
+ * {@link android.R.id#selectAll}, {@link android.R.id#cut}, {@link android.R.id#copy} or
+ * {@link android.R.id#paste} ids as parameters.
+ *
+ * Action click events should be handled by the custom implementation of
+ * {@link ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
+ *
+ * Note that text selection mode is not started when a TextView receives focus and the
+ * {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in
+ * that case, to allow for quick replacement.
*/
- private ActionMode.Callback getActionModeCallback() {
- if (canSelectText()) {
- return new SelectionActionModeCallback();
- }
- return null;
+ public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
+ mCustomSelectionActionModeCallback = actionModeCallback;
+ }
+
+ /**
+ * Retrieves the value set in {@link #setCustomSelectionActionModeCallback}. Default is null.
+ *
+ * @return The current custom selection callback.
+ */
+ public ActionMode.Callback getCustomSelectionActionModeCallback() {
+ return mCustomSelectionActionModeCallback;
}
/**
@@ -7884,7 +7908,8 @@
return false;
}
- ActionMode.Callback actionModeCallback = getActionModeCallback();
+ selectCurrentWord();
+ ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
if (actionModeCallback != null) {
mSelectionActionMode = startActionMode(actionModeCallback);
return mSelectionActionMode != null;
@@ -7950,6 +7975,12 @@
sLastCutOrCopyTime = SystemClock.uptimeMillis();
}
+ /**
+ * An ActionMode Callback class that is used to provide actions while in text selection mode.
+ *
+ * The default callback provides a subset of Select All, Cut, Copy and Paste actions, depending
+ * on which of these this TextView supports.
+ */
private class SelectionActionModeCallback implements ActionMode.Callback {
@Override
@@ -7968,48 +7999,47 @@
mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
mode.setSubtitle(null);
- boolean atLeastOne = false;
-
if (canSelectText()) {
- selectCurrentWord();
-
menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- atLeastOne = true;
}
if (canCut()) {
menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
- setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModeCutDrawable, 0)).
+ setIcon(styledAttributes.getResourceId(
+ R.styleable.Theme_actionModeCutDrawable, 0)).
setAlphabeticShortcut('x').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- atLeastOne = true;
}
if (canCopy()) {
menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
- setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModeCopyDrawable, 0)).
+ setIcon(styledAttributes.getResourceId(
+ R.styleable.Theme_actionModeCopyDrawable, 0)).
setAlphabeticShortcut('c').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- atLeastOne = true;
}
if (canPaste()) {
menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
- setIcon(styledAttributes.getResourceId(R.styleable.Theme_actionModePasteDrawable, 0)).
+ setIcon(styledAttributes.getResourceId(
+ R.styleable.Theme_actionModePasteDrawable, 0)).
setAlphabeticShortcut('v').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
- atLeastOne = true;
}
styledAttributes.recycle();
- if (atLeastOne) {
+ if (mCustomSelectionActionModeCallback != null) {
+ mCustomSelectionActionModeCallback.onCreateActionMode(mode, menu);
+ }
+
+ if (menu.hasVisibleItems() || mode.getCustomView() != null) {
getSelectionController().show();
return true;
} else {
@@ -8019,15 +8049,23 @@
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ if (mCustomSelectionActionModeCallback != null) {
+ return mCustomSelectionActionModeCallback.onPrepareActionMode(mode, menu);
+ }
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ if (mCustomSelectionActionModeCallback != null &&
+ mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
+ return true;
+ }
+
final int itemId = item.getItemId();
if (itemId == ID_SELECT_ALL) {
- Selection.setSelection((Spannable) mText, 0, mText.length());
+ selectAll();
// Update controller positions after selection change.
if (hasSelectionController()) {
getSelectionController().show();
@@ -8070,6 +8108,9 @@
@Override
public void onDestroyActionMode(ActionMode mode) {
+ if (mCustomSelectionActionModeCallback != null) {
+ mCustomSelectionActionModeCallback.onDestroyActionMode(mode);
+ }
Selection.setSelection((Spannable) mText, getSelectionStart());
hideSelectionModifierCursorController();
mSelectionActionMode = null;
@@ -8744,7 +8785,8 @@
// Double tap detection
long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
- if (duration <= ViewConfiguration.getDoubleTapTimeout()) {
+ if (duration <= ViewConfiguration.getDoubleTapTimeout() &&
+ isPositionOnText(x, y)) {
final int deltaX = x - mPreviousTapPositionX;
final int deltaY = y - mPreviousTapPositionY;
final int distanceSquared = deltaX * deltaX + deltaY * deltaY;
@@ -8923,66 +8965,14 @@
TextView.this.requestFocus();
return true;
- case DragEvent.ACTION_DRAG_LOCATION: {
+ case DragEvent.ACTION_DRAG_LOCATION:
final int offset = getOffset((int) event.getX(), (int) event.getY());
Selection.setSelection((Spannable)mText, offset);
return true;
- }
- case DragEvent.ACTION_DROP: {
- StringBuilder content = new StringBuilder("");
- ClipData clipData = event.getClipData();
- final int itemCount = clipData.getItemCount();
- for (int i=0; i < itemCount; i++) {
- Item item = clipData.getItem(i);
- content.append(item.coerceToText(TextView.this.mContext));
- }
-
- final int offset = getOffset((int) event.getX(), (int) event.getY());
-
- if (mDragSourcePositions != -1) {
- final int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions);
- final int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions);
- if (offset >= dragSourceStart && offset < dragSourceEnd) {
- // A drop inside the original selection discards the drop.
- return true;
- }
- }
-
- final int originalLength = mText.length();
- long minMax = prepareSpacesAroundPaste(offset, offset, content);
- int min = extractRangeStartFromLong(minMax);
- int max = extractRangeEndFromLong(minMax);
-
- Selection.setSelection((Spannable) mText, max);
- ((Editable) mText).replace(min, max, content);
-
- if (mDragSourcePositions != -1) {
- int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions);
- int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions);
- if (max <= dragSourceStart) {
- // Inserting text before selection has shifted positions
- final int shift = mText.length() - originalLength;
- dragSourceStart += shift;
- dragSourceEnd += shift;
- }
-
- // Delete original selection
- ((Editable) mText).delete(dragSourceStart, dragSourceEnd);
-
- // Make sure we do not leave two adjacent spaces.
- if ((dragSourceStart == 0 ||
- Character.isSpaceChar(mTransformed.charAt(dragSourceStart - 1))) &&
- (dragSourceStart == mText.length() ||
- Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
- final int pos = dragSourceStart == mText.length() ?
- dragSourceStart - 1 : dragSourceStart;
- ((Editable) mText).delete(pos, pos + 1);
- }
- }
-
+ case DragEvent.ACTION_DROP:
+ onDrop(event);
return true;
- }
case DragEvent.ACTION_DRAG_ENDED:
mDragSourcePositions = -1;
@@ -8994,6 +8984,59 @@
}
}
+ private void onDrop(DragEvent event) {
+ StringBuilder content = new StringBuilder("");
+ ClipData clipData = event.getClipData();
+ final int itemCount = clipData.getItemCount();
+ for (int i=0; i < itemCount; i++) {
+ Item item = clipData.getItem(i);
+ content.append(item.coerceToText(TextView.this.mContext));
+ }
+
+ final int offset = getOffset((int) event.getX(), (int) event.getY());
+
+ if (mDragSourcePositions != -1) {
+ final int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions);
+ final int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions);
+ if (offset >= dragSourceStart && offset < dragSourceEnd) {
+ // A drop inside the original selection discards the drop.
+ return;
+ }
+ }
+
+ final int originalLength = mText.length();
+ long minMax = prepareSpacesAroundPaste(offset, offset, content);
+ int min = extractRangeStartFromLong(minMax);
+ int max = extractRangeEndFromLong(minMax);
+
+ Selection.setSelection((Spannable) mText, max);
+ ((Editable) mText).replace(min, max, content);
+
+ if (mDragSourcePositions != -1) {
+ int dragSourceStart = extractRangeStartFromLong(mDragSourcePositions);
+ int dragSourceEnd = extractRangeEndFromLong(mDragSourcePositions);
+ if (max <= dragSourceStart) {
+ // Inserting text before selection has shifted positions
+ final int shift = mText.length() - originalLength;
+ dragSourceStart += shift;
+ dragSourceEnd += shift;
+ }
+
+ // Delete original selection
+ ((Editable) mText).delete(dragSourceStart, dragSourceEnd);
+
+ // Make sure we do not leave two adjacent spaces.
+ if ((dragSourceStart == 0 ||
+ Character.isSpaceChar(mTransformed.charAt(dragSourceStart - 1))) &&
+ (dragSourceStart == mText.length() ||
+ Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
+ final int pos = dragSourceStart == mText.length() ?
+ dragSourceStart - 1 : dragSourceStart;
+ ((Editable) mText).delete(pos, pos + 1);
+ }
+ }
+ }
+
/**
* @return True if this view supports insertion handles.
*/
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 20402a3..447a062 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -70,6 +70,10 @@
private ActionMode mActionMode;
+ private boolean mLastMenuVisibility;
+ private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
+ new ArrayList<OnMenuVisibilityListener>();
+
private static final int CONTEXT_DISPLAY_NORMAL = 0;
private static final int CONTEXT_DISPLAY_SPLIT = 1;
@@ -120,6 +124,26 @@
CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
}
+ public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
+ mMenuVisibilityListeners.add(listener);
+ }
+
+ public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
+ mMenuVisibilityListeners.remove(listener);
+ }
+
+ public void dispatchMenuVisibilityChanged(boolean isVisible) {
+ if (isVisible == mLastMenuVisibility) {
+ return;
+ }
+ mLastMenuVisibility = isVisible;
+
+ final int count = mMenuVisibilityListeners.size();
+ for (int i = 0; i < count; i++) {
+ mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
+ }
+ }
+
@Override
public void setTitle(int resId) {
setTitle(mContext.getString(resId));
@@ -138,11 +162,11 @@
mActionView.setCallback(null);
}
- public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
+ public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback) {
setDropdownNavigationMode(adapter, callback, -1);
}
- public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback,
+ public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback,
int defaultSelectedPosition) {
cleanupTabs();
setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
@@ -516,7 +540,7 @@
public void onMenuModeChange(MenuBuilder menu) {
invalidate();
- mUpperContextView.showOverflowMenu();
+ mUpperContextView.openOverflowMenu();
}
}
@@ -627,7 +651,7 @@
}
@Override
- public void setListNavigationCallbacks(SpinnerAdapter adapter, NavigationCallback callback) {
+ public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
mActionView.setDropdownAdapter(adapter);
mActionView.setCallback(callback);
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index b2810b1..e384320 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -118,6 +118,12 @@
private int mCheckedItem = -1;
+ private int mAlertDialogLayout;
+ private int mListLayout;
+ private int mMultiChoiceItemLayout;
+ private int mSingleChoiceItemLayout;
+ private int mListItemLayout;
+
private Handler mHandler;
View.OnClickListener mButtonHandler = new View.OnClickListener() {
@@ -178,6 +184,27 @@
mDialogInterface = di;
mWindow = window;
mHandler = new ButtonHandler(di);
+
+ TypedArray a = context.obtainStyledAttributes(null,
+ com.android.internal.R.styleable.AlertDialog,
+ com.android.internal.R.attr.alertDialogStyle, 0);
+
+ mAlertDialogLayout = a.getResourceId(com.android.internal.R.styleable.AlertDialog_layout,
+ com.android.internal.R.layout.alert_dialog);
+ mListLayout = a.getResourceId(
+ com.android.internal.R.styleable.AlertDialog_listLayout,
+ com.android.internal.R.layout.select_dialog);
+ mMultiChoiceItemLayout = a.getResourceId(
+ com.android.internal.R.styleable.AlertDialog_multiChoiceItemLayout,
+ com.android.internal.R.layout.select_dialog_multichoice);
+ mSingleChoiceItemLayout = a.getResourceId(
+ com.android.internal.R.styleable.AlertDialog_singleChoiceItemLayout,
+ com.android.internal.R.layout.select_dialog_singlechoice);
+ mListItemLayout = a.getResourceId(
+ com.android.internal.R.styleable.AlertDialog_listItemLayout,
+ com.android.internal.R.layout.select_dialog_item);
+
+ a.recycle();
}
static boolean canTextInput(View v) {
@@ -210,7 +237,7 @@
mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
- mWindow.setContentView(com.android.internal.R.layout.alert_dialog);
+ mWindow.setContentView(mAlertDialogLayout);
setupView();
}
@@ -810,13 +837,13 @@
private void createListView(final AlertController dialog) {
final RecycleListView listView = (RecycleListView)
- mInflater.inflate(R.layout.select_dialog, null);
+ mInflater.inflate(dialog.mListLayout, null);
ListAdapter adapter;
if (mIsMultiChoice) {
if (mCursor == null) {
adapter = new ArrayAdapter<CharSequence>(
- mContext, R.layout.select_dialog_multichoice, R.id.text1, mItems) {
+ mContext, dialog.mMultiChoiceItemLayout, R.id.text1, mItems) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
@@ -850,7 +877,7 @@
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.select_dialog_multichoice,
+ return mInflater.inflate(dialog.mMultiChoiceItemLayout,
parent, false);
}
@@ -858,7 +885,7 @@
}
} else {
int layout = mIsSingleChoice
- ? R.layout.select_dialog_singlechoice : R.layout.select_dialog_item;
+ ? dialog.mSingleChoiceItemLayout : dialog.mListItemLayout;
if (mCursor == null) {
adapter = (mAdapter != null) ? mAdapter
: new ArrayAdapter<CharSequence>(mContext, layout, R.id.text1, mItems);
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index c930c57c..bfef275 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -27,6 +27,7 @@
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.ThreadFactory;
import android.content.pm.PackageInfo;
import android.util.Log;
@@ -43,27 +44,40 @@
private static final boolean enabled;
private static final Executor snapshotWriter;
- private static final int samplingProfilerHz;
-
- /** Whether or not we've created the snapshots dir. */
- private static boolean dirMade = false;
+ private static final int samplingProfilerMilliseconds;
+ private static final int samplingProfilerDepth;
/** Whether or not a snapshot is being persisted. */
private static final AtomicBoolean pending = new AtomicBoolean(false);
static {
- samplingProfilerHz = SystemProperties.getInt("persist.sys.profiler_hz", 0);
- // Disabling this for now, as it crashes when enabled server-side. So adding
- // a new property ("REALLY") for those wanting to test and fix it.
- boolean really = SystemProperties.getInt("persist.sys.profiler_hz_REALLY", 0) > 0;
- if (samplingProfilerHz > 0 && really) {
- snapshotWriter = Executors.newSingleThreadExecutor();
- enabled = true;
- Log.i(TAG, "Profiler is enabled. Sampling Profiler Hz: " + samplingProfilerHz);
+ samplingProfilerMilliseconds = SystemProperties.getInt("persist.sys.profiler_ms", 0);
+ samplingProfilerDepth = SystemProperties.getInt("persist.sys.profiler_depth", 4);
+ if (samplingProfilerMilliseconds > 0) {
+ File dir = new File(SNAPSHOT_DIR);
+ dir.mkdirs();
+ // the directory needs to be writable to anybody to allow file writing
+ dir.setWritable(true, false);
+ // the directory needs to be executable to anybody to allow file creation
+ dir.setExecutable(true, false);
+ if (dir.isDirectory()) {
+ snapshotWriter = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ return new Thread(r, TAG);
+ }
+ });
+ enabled = true;
+ Log.i(TAG, "Profiling enabled. Sampling interval ms: "
+ + samplingProfilerMilliseconds);
+ } else {
+ snapshotWriter = null;
+ enabled = true;
+ Log.w(TAG, "Profiling setup failed. Could not create " + SNAPSHOT_DIR);
+ }
} else {
snapshotWriter = null;
enabled = false;
- Log.i(TAG, "Profiler is disabled.");
+ Log.i(TAG, "Profiling disabled.");
}
}
@@ -85,8 +99,8 @@
}
ThreadGroup group = Thread.currentThread().getThreadGroup();
SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group);
- INSTANCE = new SamplingProfiler(4, threadSet); // TODO parameter for depth
- INSTANCE.start(1000/samplingProfilerHz);
+ INSTANCE = new SamplingProfiler(samplingProfilerDepth, threadSet);
+ INSTANCE.start(samplingProfilerMilliseconds);
}
/**
@@ -106,25 +120,8 @@
if (pending.compareAndSet(false, true)) {
snapshotWriter.execute(new Runnable() {
public void run() {
- if (!dirMade) {
- File dir = new File(SNAPSHOT_DIR);
- dir.mkdirs();
- // the directory needs to be writable to anybody
- dir.setWritable(true, false);
- // the directory needs to be executable to anybody
- // don't know why yet, but mode 723 would work, while
- // mode 722 throws FileNotFoundExecption at line 151
- dir.setExecutable(true, false);
- if (new File(SNAPSHOT_DIR).isDirectory()) {
- dirMade = true;
- } else {
- Log.w(TAG, "Creation of " + SNAPSHOT_DIR + " failed.");
- pending.set(false);
- return;
- }
- }
try {
- writeSnapshot(SNAPSHOT_DIR, processName, packageInfo);
+ writeSnapshotFile(processName, packageInfo);
} finally {
pending.set(false);
}
@@ -140,7 +137,7 @@
if (!enabled) {
return;
}
- writeSnapshot("zygote", null);
+ writeSnapshotFile("zygote", null);
INSTANCE.shutdown();
INSTANCE = null;
}
@@ -148,7 +145,7 @@
/**
* pass in PackageInfo to retrieve various values for snapshot header
*/
- private static void writeSnapshot(String dir, String processName, PackageInfo packageInfo) {
+ private static void writeSnapshotFile(String processName, PackageInfo packageInfo) {
if (!enabled) {
return;
}
@@ -161,7 +158,7 @@
*/
long start = System.currentTimeMillis();
String name = processName.replaceAll(":", ".");
- String path = dir + "/" + name + "-" +System.currentTimeMillis() + ".snapshot";
+ String path = SNAPSHOT_DIR + "/" + name + "-" +System.currentTimeMillis() + ".snapshot";
PrintStream out = null;
try {
out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path)));
diff --git a/core/java/com/android/internal/util/AsyncChannel.java b/core/java/com/android/internal/util/AsyncChannel.java
index 0891acc..101dd91 100644
--- a/core/java/com/android/internal/util/AsyncChannel.java
+++ b/core/java/com/android/internal/util/AsyncChannel.java
@@ -95,7 +95,7 @@
*
* msg.arg1 == 0 : STATUS_SUCCESSFUL
* 1 : STATUS_BINDING_UNSUCCESSFUL
- * msg.arg2 == token parameter
+ * msg.obj == the AsyncChannel
* msg.replyTo == dstMessenger if successful
*/
public static final int CMD_CHANNEL_HALF_CONNECTED = -1;
@@ -136,7 +136,7 @@
*
* msg.arg1 == 0 : STATUS_SUCCESSFUL
* : All other values signify failure and the channel state is indeterminate
- * msg.arg2 == token parameter
+ * msg.obj == the AsyncChannel
* msg.replyTo = messenger disconnecting or null if it was never connected.
*/
public static final int CMD_CHANNEL_DISCONNECTED = -5;
@@ -179,14 +179,12 @@
* @param dstPackageName is the destination package name
* @param dstClassName is the fully qualified class name (i.e. contains
* package name)
- * @param token unique id for this connection
*/
private void connectSrcHandlerToPackage(
- Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName,
- int token) {
+ Context srcContext, Handler srcHandler, String dstPackageName, String dstClassName) {
if (DBG) log("connect srcHandler to dst Package & class E");
- mConnection = new AsyncChannelConnection(token);
+ mConnection = new AsyncChannelConnection();
/* Initialize the source information */
mSrcContext = srcContext;
@@ -205,7 +203,7 @@
intent.setClassName(dstPackageName, dstClassName);
boolean result = srcContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
if (!result) {
- replyHalfConnected(STATUS_BINDING_UNSUCCESSFUL, token);
+ replyHalfConnected(STATUS_BINDING_UNSUCCESSFUL);
}
if (DBG) log("connect srcHandler to dst Package & class X result=" + result);
@@ -216,7 +214,7 @@
*
* Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
* msg.arg1 = status
- * msg.arg2 = token
+ * msg.obj = the AsyncChannel
*
* @param srcContext is the context of the source
* @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
@@ -224,10 +222,9 @@
* @param dstPackageName is the destination package name
* @param dstClassName is the fully qualified class name (i.e. contains
* package name)
- * @param token returned in msg.arg2
*/
public void connect(Context srcContext, Handler srcHandler, String dstPackageName,
- String dstClassName, int token) {
+ String dstClassName) {
if (DBG) log("connect srcHandler to dst Package & class E");
final class ConnectAsync implements Runnable {
@@ -235,25 +232,21 @@
Handler mSrcHdlr;
String mDstPackageName;
String mDstClassName;
- int mToken;
ConnectAsync(Context srcContext, Handler srcHandler, String dstPackageName,
- String dstClassName, int token) {
+ String dstClassName) {
mSrcCtx = srcContext;
mSrcHdlr = srcHandler;
mDstPackageName = dstPackageName;
mDstClassName = dstClassName;
- mToken = token;
}
public void run() {
- connectSrcHandlerToPackage(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName,
- mToken);
+ connectSrcHandlerToPackage(mSrcCtx, mSrcHdlr, mDstPackageName, mDstClassName);
}
}
- ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName,
- token);
+ ConnectAsync ca = new ConnectAsync(srcContext, srcHandler, dstPackageName, dstClassName);
new Thread(ca).start();
if (DBG) log("connect srcHandler to dst Package & class X");
@@ -264,15 +257,14 @@
*
* Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
* msg.arg1 = status
- * msg.arg2 = token
+ * msg.obj = the AsyncChannel
*
* @param srcContext
* @param srcHandler
* @param klass is the class to send messages to.
- * @param token returned in msg.arg2
*/
- public void connect(Context srcContext, Handler srcHandler, Class<?> klass, int token) {
- connect(srcContext, srcHandler, klass.getPackage().getName(), klass.getName(), token);
+ public void connect(Context srcContext, Handler srcHandler, Class<?> klass) {
+ connect(srcContext, srcHandler, klass.getPackage().getName(), klass.getName());
}
/**
@@ -280,14 +272,13 @@
*
* Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
* msg.arg1 = status
- * msg.arg2 = token
+ * msg.obj = the AsyncChannel
*
* @param srcContext
* @param srcHandler
* @param dstMessenger
- * @param token returned in msg.arg2
*/
- public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger, int token) {
+ public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger) {
if (DBG) log("connect srcHandler to the dstMessenger E");
// Initialize source fields
@@ -301,7 +292,7 @@
if (DBG) log("tell source we are half connected");
// Tell source we are half connected
- replyHalfConnected(STATUS_SUCCESSFUL, token);
+ replyHalfConnected(STATUS_SUCCESSFUL);
if (DBG) log("connect srcHandler to the dstMessenger X");
}
@@ -311,16 +302,15 @@
*
* Sends a CMD_CHANNEL_HALF_CONNECTED message to srcHandler when complete.
* msg.arg1 = status
- * msg.arg2 = token
+ * msg.obj = the AsyncChannel
*
* @param srcContext is the context of the source
* @param srcHandler is the hander to receive CONNECTED & DISCONNECTED
* messages
* @param dstHandler is the hander to send messages to.
- * @param token returned in msg.arg2
*/
- public void connect(Context srcContext, Handler srcHandler, Handler dstHandler, int token) {
- connect(srcContext, srcHandler, new Messenger(dstHandler), token);
+ public void connect(Context srcContext, Handler srcHandler, Handler dstHandler) {
+ connect(srcContext, srcHandler, new Messenger(dstHandler));
}
/**
@@ -328,14 +318,13 @@
*
* Sends a CMD_CHANNEL_HALF_CONNECTED message to srcAsyncService when complete.
* msg.arg1 = status
- * msg.arg2 = token
+ * msg.obj = the AsyncChannel
*
* @param srcAsyncService
* @param dstMessenger
- * @param token returned in msg.arg2
*/
- public void connect(AsyncService srcAsyncService, Messenger dstMessenger, int token) {
- connect(srcAsyncService, srcAsyncService.getHandler(), dstMessenger, token);
+ public void connect(AsyncService srcAsyncService, Messenger dstMessenger) {
+ connect(srcAsyncService, srcAsyncService.getHandler(), dstMessenger);
}
/**
@@ -351,15 +340,14 @@
/**
* Disconnect
*/
- public void disconnect(int token) {
+ public void disconnect() {
if (mConnection != null) {
- mConnection.setToken(token);
mSrcContext.unbindService(mConnection);
}
if (mSrcHandler != null) {
Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
msg.arg1 = STATUS_SUCCESSFUL;
- msg.arg2 = token;
+ msg.obj = this;
msg.replyTo = mDstMessenger;
mSrcHandler.sendMessage(msg);
}
@@ -727,10 +715,10 @@
*
* @param status to be stored in msg.arg1
*/
- private void replyHalfConnected(int status, int token) {
+ private void replyHalfConnected(int status) {
Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_HALF_CONNECTED);
msg.arg1 = status;
- msg.arg2 = token;
+ msg.obj = this;
msg.replyTo = mDstMessenger;
mSrcHandler.sendMessage(msg);
}
@@ -739,28 +727,18 @@
* ServiceConnection to receive call backs.
*/
class AsyncChannelConnection implements ServiceConnection {
- private int mToken;
-
- AsyncChannelConnection(int token) {
- mToken = token;
- }
-
- /**
- * @param token
- */
- public void setToken(int token) {
- mToken = token;
+ AsyncChannelConnection() {
}
public void onServiceConnected(ComponentName className, IBinder service) {
mDstMessenger = new Messenger(service);
- replyHalfConnected(STATUS_SUCCESSFUL, mToken);
+ replyHalfConnected(STATUS_SUCCESSFUL);
}
public void onServiceDisconnected(ComponentName className) {
Message msg = mSrcHandler.obtainMessage(CMD_CHANNEL_DISCONNECTED);
msg.arg1 = STATUS_SUCCESSFUL;
- msg.arg2 = mToken;
+ msg.obj = AsyncChannel.this;
msg.replyTo = mDstMessenger;
mSrcHandler.sendMessage(msg);
}
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index b54daba..2d067da 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -135,6 +135,6 @@
public void onMenuModeChange(MenuBuilder menu) {
invalidate();
- mContextView.showOverflowMenu();
+ mContextView.openOverflowMenu();
}
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index 621defe..84067d0 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -59,6 +59,22 @@
}
};
+ private class OpenOverflowRunnable implements Runnable {
+ private MenuPopupHelper mPopup;
+
+ public OpenOverflowRunnable(MenuPopupHelper popup) {
+ mPopup = popup;
+ }
+
+ public void run() {
+ mOverflowPopup = mPopup;
+ mPopup.show();
+ mPostedOpenRunnable = null;
+ }
+ }
+
+ private OpenOverflowRunnable mPostedOpenRunnable;
+
public ActionMenuView(Context context) {
this(context, null);
}
@@ -100,6 +116,7 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
final int screen = newConfig.screenLayout;
mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE;
@@ -115,6 +132,14 @@
}
}
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mOverflowPopup != null && mOverflowPopup.isShowing()) {
+ mOverflowPopup.dismiss();
+ }
+ }
+
private int getMaxActionButtons() {
return getResources().getInteger(com.android.internal.R.integer.max_action_buttons);
}
@@ -193,30 +218,34 @@
}
public boolean showOverflowMenu() {
- if (mOverflowButton != null) {
- final MenuPopupHelper popup =
- new MenuPopupHelper(getContext(), mMenu, mOverflowButton, true);
- // Post this for later; we might still need a layout for the anchor to be right.
- post(new Runnable() {
- public void run() {
- popup.show();
- }
- });
- mOverflowPopup = popup;
+ if (mOverflowButton != null && !isOverflowMenuShowing()) {
+ mMenu.getCallback().onMenuModeChange(mMenu);
return true;
}
return false;
}
+ public void openOverflowMenu() {
+ OverflowPopup popup = new OverflowPopup(getContext(), mMenu, mOverflowButton, true);
+ mPostedOpenRunnable = new OpenOverflowRunnable(popup);
+ // Post this for later; we might still need a layout for the anchor to be right.
+ post(mPostedOpenRunnable);
+ }
+
public boolean isOverflowMenuShowing() {
- MenuPopupHelper popup = mOverflowPopup;
- if (popup != null) {
- return popup.isShowing();
- }
- return false;
+ return mOverflowPopup != null && mOverflowPopup.isShowing();
+ }
+
+ public boolean isOverflowMenuOpen() {
+ return mOverflowPopup != null;
}
public boolean hideOverflowMenu() {
+ if (mPostedOpenRunnable != null) {
+ removeCallbacks(mPostedOpenRunnable);
+ return true;
+ }
+
MenuPopupHelper popup = mOverflowPopup;
if (popup != null) {
popup.dismiss();
@@ -274,9 +303,22 @@
return true;
}
- // Change to overflow mode
- mMenu.getCallback().onMenuModeChange(mMenu);
+ showOverflowMenu();
return true;
}
}
+
+ private class OverflowPopup extends MenuPopupHelper {
+ public OverflowPopup(Context context, MenuBuilder menu, View anchorView,
+ boolean overflowOnly) {
+ super(context, menu, anchorView, overflowOnly);
+ }
+
+ @Override
+ public void onDismiss() {
+ super.onDismiss();
+ mMenu.getCallback().onCloseMenu(mMenu, true);
+ mOverflowPopup = null;
+ }
+ }
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 1406e4e..2cb78a5 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -35,7 +35,7 @@
* @hide
*/
public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener,
- ViewTreeObserver.OnGlobalLayoutListener {
+ ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener {
private static final String TAG = "MenuPopupHelper";
private Context mContext;
@@ -46,12 +46,6 @@
private boolean mOverflowOnly;
private ViewTreeObserver mTreeObserver;
- private PopupWindow.OnDismissListener mDismissListener = new PopupWindow.OnDismissListener() {
- public void onDismiss() {
- mPopup = null;
- }
- };
-
public MenuPopupHelper(Context context, MenuBuilder menu) {
this(context, menu, null, false);
}
@@ -77,7 +71,7 @@
public void show() {
mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle);
mPopup.setOnItemClickListener(this);
- mPopup.setOnDismissListener(mDismissListener);
+ mPopup.setOnDismissListener(this);
final MenuAdapter adapter = mOverflowOnly ?
mMenu.getOverflowMenuAdapter(MenuBuilder.TYPE_POPUP) :
@@ -110,8 +104,12 @@
if (isShowing()) {
mPopup.dismiss();
}
+ }
+
+ public void onDismiss() {
+ mPopup = null;
if (mTreeObserver != null) {
- mTreeObserver.removeGlobalOnLayoutListener(this);
+ mTreeObserver.removeGlobalOnLayoutListener(MenuPopupHelper.this);
mTreeObserver = null;
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index e93c414..cbf12bf 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -180,6 +180,12 @@
return false;
}
+ public void openOverflowMenu() {
+ if (mMenuView != null) {
+ mMenuView.openOverflowMenu();
+ }
+ }
+
public boolean hideOverflowMenu() {
if (mMenuView != null) {
return mMenuView.hideOverflowMenu();
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index f931217..07a65fc 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -22,7 +22,7 @@
import com.android.internal.view.menu.MenuBuilder;
import android.app.ActionBar;
-import android.app.ActionBar.NavigationCallback;
+import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -114,7 +114,7 @@
private ActionMenuItem mLogoNavItem;
private SpinnerAdapter mSpinnerAdapter;
- private NavigationCallback mCallback;
+ private OnNavigationListener mCallback;
private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
new AdapterView.OnItemSelectedListener() {
@@ -243,7 +243,7 @@
return null;
}
- public void setCallback(NavigationCallback callback) {
+ public void setCallback(OnNavigationListener callback) {
mCallback = callback;
}
@@ -269,6 +269,12 @@
return false;
}
+ public void openOverflowMenu() {
+ if (mMenuView != null) {
+ mMenuView.openOverflowMenu();
+ }
+ }
+
public void postShowOverflowMenu() {
post(new Runnable() {
public void run() {
@@ -291,6 +297,13 @@
return false;
}
+ public boolean isOverflowMenuOpen() {
+ if (mMenuView != null) {
+ return mMenuView.isOverflowMenuOpen();
+ }
+ return false;
+ }
+
public boolean isOverflowReserved() {
return mMenuView != null && mMenuView.isOverflowReserved();
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ddc63dd..a2666e2 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1013,7 +1013,7 @@
<permission android:name="android.permission.SHUTDOWN"
android:label="@string/permlab_shutdown"
android:description="@string/permdesc_shutdown"
- android:protectionLevel="signature" />
+ android:protectionLevel="signatureOrSystem" />
<!-- Allows an application to tell the activity manager to temporarily
stop application switches, putting it into a special mode that
diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..8bb4048
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png
new file mode 100644
index 0000000..fdd3ee7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
index 87d9c21..ab6abdc 100644
--- a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
index 720ee78..dbdfc79 100644
--- a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
index 4275da07..4eba040 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
index 3ec9c1f..b186730 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
index 227bde2..06190a1 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
index 6ddfab0..8c16566 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..0ce5d13
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_focused_holo_light.9.png
new file mode 100644
index 0000000..945516e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png b/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png
new file mode 100644
index 0000000..2993b44
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png
new file mode 100644
index 0000000..33e6dc8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png
new file mode 100644
index 0000000..eb0d90f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
index 09ca253..74c02c2 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
index 0a7d3a1..345f4f5 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
index 54a1519..40e5db3 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
index 06ca0d4..0cbf6d2 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
index 9015299..bc56916 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
index b355cb3..84adf68 100644
--- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png
new file mode 100644
index 0000000..4a98e57
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png
new file mode 100644
index 0000000..5cf6bf3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png b/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png
new file mode 100644
index 0000000..4aad237
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png
new file mode 100644
index 0000000..8bb4048
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png
new file mode 100644
index 0000000..fdd3ee7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
index c98c951..ab6abdc 100644
--- a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
index 7691f81..dbdfc79 100644
--- a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
index fab86ac..06190a1 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
index 876eb794..8c16566 100644
--- a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_focused_holo_dark.9.png
new file mode 100644
index 0000000..0ce5d13
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_focused_holo_light.9.png
new file mode 100644
index 0000000..945516e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png b/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png
new file mode 100644
index 0000000..2993b44
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png
new file mode 100644
index 0000000..33e6dc8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png
new file mode 100644
index 0000000..eb0d90f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png
index 2646899..44a5d82 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png
index 374d457..6613683 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
index 65c87ba..74c02c2 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
index 724b3fd..345f4f5 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
index 2cc7f62..bc56916 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
index a2d9d8a..84adf68 100644
--- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png
new file mode 100644
index 0000000..4a98e57
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png
new file mode 100644
index 0000000..5cf6bf3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png b/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png
new file mode 100644
index 0000000..4aad237
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png
Binary files differ
diff --git a/core/res/res/drawable/edit_text_holo_dark.xml b/core/res/res/drawable/edit_text_holo_dark.xml
index 63ccd1d..29a5150c 100644
--- a/core/res/res/drawable/edit_text_holo_dark.xml
+++ b/core/res/res/drawable/edit_text_holo_dark.xml
@@ -17,7 +17,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" />
<item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_holo_dark" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_active_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_activated_holo_dark" />
+ <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_focused_holo_dark" />
<item android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" />
<item android:state_focused="true" android:drawable="@drawable/textfield_disabled_focused_holo_dark" />
<item android:drawable="@drawable/textfield_disabled_holo_dark" />
diff --git a/core/res/res/drawable/edit_text_holo_light.xml b/core/res/res/drawable/edit_text_holo_light.xml
index 324acda..5426916 100644
--- a/core/res/res/drawable/edit_text_holo_light.xml
+++ b/core/res/res/drawable/edit_text_holo_light.xml
@@ -17,7 +17,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_light" />
<item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_holo_light" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_active_holo_light" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_activated_holo_light" />
+ <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_focused_holo_light" />
<item android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_light" />
<item android:state_focused="true" android:drawable="@drawable/textfield_disabled_focused_holo_light" />
<item android:drawable="@drawable/textfield_disabled_holo_light" />
diff --git a/core/res/res/drawable/edit_text_multiline_holo_dark.xml b/core/res/res/drawable/edit_text_multiline_holo_dark.xml
index 67d2748..d20ea19 100644
--- a/core/res/res/drawable/edit_text_multiline_holo_dark.xml
+++ b/core/res/res/drawable/edit_text_multiline_holo_dark.xml
@@ -17,7 +17,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_dark" />
<item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_multiline_disabled_holo_dark" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_active_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_activated_holo_dark" />
+ <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_multiline_focused_holo_dark" />
<item android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_dark" />
<item android:state_focused="true" android:drawable="@drawable/textfield_multiline_disabled_focused_holo_dark" />
<item android:drawable="@drawable/textfield_multiline_disabled_holo_dark" />
diff --git a/core/res/res/drawable/edit_text_multiline_holo_light.xml b/core/res/res/drawable/edit_text_multiline_holo_light.xml
index 08b3ec6..41a4eab 100644
--- a/core/res/res/drawable/edit_text_multiline_holo_light.xml
+++ b/core/res/res/drawable/edit_text_multiline_holo_light.xml
@@ -17,7 +17,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_light" />
<item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_multiline_disabled_holo_light" />
- <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_active_holo_light" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_activated_holo_light" />
+ <item android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_multiline_focused_holo_light" />
<item android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_light" />
<item android:state_focused="true" android:drawable="@drawable/textfield_multiline_disabled_focused_holo_light" />
<item android:drawable="@drawable/textfield_multiline_disabled_holo_light" />
diff --git a/core/res/res/layout-xlarge/alert_dialog_holo.xml b/core/res/res/layout-xlarge/alert_dialog_holo.xml
index 72b1e31..6790a81 100644
--- a/core/res/res/layout-xlarge/alert_dialog_holo.xml
+++ b/core/res/res/layout-xlarge/alert_dialog_holo.xml
@@ -74,14 +74,17 @@
<ScrollView android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="16dip"
+ android:layout_marginRight="16dip"
android:paddingTop="32dip"
android:paddingBottom="32dip"
- android:paddingLeft="32dip"
- android:paddingRight="32dip">
+ android:clipToPadding="false">
<TextView android:id="@+id/message"
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip" />
</ScrollView>
</LinearLayout>
@@ -93,19 +96,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dip"
- android:paddingBottom="8dip" />
+ android:paddingBottom="8dip"
+ android:paddingLeft="32dip"
+ android:paddingRight="32dip" />
</FrameLayout>
<LinearLayout android:id="@+id/buttonPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="54dip"
- android:orientation="vertical" >
+ android:orientation="vertical"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="beginning"
+ android:dividerPadding="16dip">
<LinearLayout
+ style="?android:attr/buttonGroupStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:paddingTop="4dip"
android:paddingLeft="2dip"
android:paddingRight="2dip"
android:measureWithLargestChild="true">
@@ -120,18 +128,21 @@
android:layout_gravity="left"
android:layout_weight="1"
android:maxLines="2"
+ style="?android:attr/borderlessButtonStyle"
android:layout_height="wrap_content" />
<Button android:id="@+id/button3"
android:layout_width="0dip"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:maxLines="2"
+ style="?android:attr/borderlessButtonStyle"
android:layout_height="wrap_content" />
<Button android:id="@+id/button2"
android:layout_width="0dip"
android:layout_gravity="right"
android:layout_weight="1"
android:maxLines="2"
+ style="?android:attr/borderlessButtonStyle"
android:layout_height="wrap_content" />
<LinearLayout android:id="@+id/rightSpacer"
android:layout_width="0dip"
diff --git a/core/res/res/layout-xlarge/select_dialog_holo.xml b/core/res/res/layout-xlarge/select_dialog_holo.xml
new file mode 100644
index 0000000..7c95693
--- /dev/null
+++ b/core/res/res/layout-xlarge/select_dialog_holo.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!--
+ This layout file is used by the AlertDialog when displaying a list of items.
+ This layout file is inflated and used as the ListView to display the items.
+ Assign an ID so its state will be saved/restored.
+-->
+<view class="com.android.internal.app.AlertController$RecycleListView"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+android:id/select_dialog_listview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="5dip"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:cacheColorHint="@null"
+ android:divider="?android:attr/listDividerAlertDialog"
+ android:scrollbars="vertical"
+ android:overScrollMode="ifContentScrolls" />
diff --git a/core/res/res/layout-xlarge/select_dialog_item_holo.xml b/core/res/res/layout-xlarge/select_dialog_item_holo.xml
new file mode 100644
index 0000000..396092e
--- /dev/null
+++ b/core/res/res/layout-xlarge/select_dialog_item_holo.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!--
+ This layout file is used by the AlertDialog when displaying a list of items.
+ This layout file is inflated and used as the TextView to display individual
+ items.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:gravity="center_vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:ellipsize="marquee"
+/>
diff --git a/core/res/res/layout-xlarge/select_dialog_multichoice_holo.xml b/core/res/res/layout-xlarge/select_dialog_multichoice_holo.xml
new file mode 100644
index 0000000..8027035
--- /dev/null
+++ b/core/res/res/layout-xlarge/select_dialog_multichoice_holo.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:gravity="center_vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:checkMark="?android:attr/listChoiceIndicatorMultiple"
+ android:ellipsize="marquee"
+/>
diff --git a/core/res/res/layout-xlarge/select_dialog_singlechoice_holo.xml b/core/res/res/layout-xlarge/select_dialog_singlechoice_holo.xml
new file mode 100644
index 0000000..cab519f
--- /dev/null
+++ b/core/res/res/layout-xlarge/select_dialog_singlechoice_holo.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorAlertDialogListItem"
+ android:gravity="center_vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:checkMark="?android:attr/listChoiceIndicatorSingle"
+ android:ellipsize="marquee"
+/>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index fd4b32c..4abcc9f 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"تم إرسال عدد كبير من الرسائل القصيرة SMS. حدّد \"موافق\" للمتابعة، أو \"إلغاء\" لإيقاف الإرسال."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"موافق"</string>
<string name="sms_control_no" msgid="1715320703137199869">"إلغاء"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"تعيين"</string>
<string name="default_permission_group" msgid="2690160991405646128">"افتراضي"</string>
<string name="no_permissions" msgid="7283357728219338112">"لا أذونات مطلوبة"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e01bb9b..03206b7 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Изпращат се голям брой SMS съобщения. Изберете „OK“, за да продължите, или „Отказ“, за да спрете изпращането."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Отказ"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Задаване"</string>
<string name="default_permission_group" msgid="2690160991405646128">"По подразбиране"</string>
<string name="no_permissions" msgid="7283357728219338112">"Не се изискват разрешения"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index c32c95a..fd788e3 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"S\'estan enviant molts missatges SMS. Seleccioneu \"D\'acord\" per continuar o \"Cancel·la\" per aturar l\'enviament."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"D\'acord"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancel·la"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
<string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f65f585a..1c233f0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Bez upozornění smazat všechna data telefonu obnovením továrních dat"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Nastavit globální proxy server zařízení"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavit konec platnosti hesla"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domů"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"čtení historie a záložek Prohlížeče"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Je odesílán velký počet zpráv SMS. Vyberte OK, chcete-li pokračovat, nebo Zrušit, chcete-li odesílání ukončit."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Zrušit"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Zobrazit vše"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Úložiště USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB připojeno"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Připojili jste telefon k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače do úložiště USB zařízení Android či obráceně, vyberte následující tlačítko."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Připojili jste telefon k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače do úložiště USB zařízení Android či obráceně, vyberte následující tlačítko."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače do úložiště USB v zařízení Android či obráceně, stiskněte tlačítko níže."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače na kartu SD v zařízení Android či obráceně, stiskněte tlačítko níže."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Zapnout úložiště USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Problém s použitím úložiště USB jako velkokapacitního úložiště."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Problém s použitím karty SD jako velkokapacitního úložiště USB."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 8bb762b..5f96369 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Slet telefonens data uden varsel ved at gendanne fabriksindstillinger"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angiv enhedens globale proxy"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angiv enhedens globale proxy, der skal bruges, mens politikken er aktiveret. Kun den første enhedsadministrator angiver den effektive globale proxy."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Indstil udløb for adgangskode"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"læs browserens oversigt og bogmærker"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Der sendes et stort antal sms-beskeder. Vælg \"OK\" for at fortsætte eller \"Annuller\" for at stoppe afsendelsen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annuller"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Angiv"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-masselagring"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB er tilsluttet"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har forbundet din telefon til din computer via USB. Vælg knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids USB-lager."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har forbundet din telefon til din computer via USB. Vælg knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids USB-lager."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har fået forbindelse til din computer via USB. Vælg knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids USB-lager."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har fået forbindelse til din computer via USB. Vælg knappen nedenfor, hvis du ønsker at kopiere filer mellem din computer og din Androids SD-kort."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå USB-lagringen til"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Der opstod et problem med at bruge USB-lager til USB-masselager."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Der opstod et problem med at bruge dit SD-kort til USB-masselager."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 87e57ce..8aa24d9 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Auf Werkseinstellungen zurücksetzen und Daten auf dem Telefon ohne Warnung löschen"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Den globalen Proxy des Geräts festlegen"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den globalen Proxy des Geräts zur Verwendung während der Aktivierung der Richtlinie festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Ablauf des Passworts festlegen"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Browserverlauf und Lesezeichen lesen"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Es werden eine große Anzahl an Kurznachrichten versendet. Wählen Sie \"OK\", um fortzufahren, oder drücken Sie auf \"Abbrechen\", um den Sendevorgang zu beenden."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Abbrechen"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Einstellen"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Alle anzeigen"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-Massenspeicher"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-Verbindung"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Wählen Sie die Schaltfläche unten aus, wenn Sie Dateien von Ihrem Computer in den USB-Speicher Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Wählen Sie die Schaltfläche unten aus, wenn Sie Dateien von Ihrem Computer in den USB-Speicher Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Berühren Sie die Schaltfläche unten, wenn Sie Dateien von Ihrem Computer in den USB-Speicher Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Sie haben Ihr Telefon über USB mit Ihrem Computer verbunden. Berühren Sie die Schaltfläche unten, wenn Sie Dateien von Ihrem Computer auf die SD-Karte Ihres Android-Geräts und umgekehrt kopieren möchten."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB-Speicher aktivieren"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Bei der Verwendung Ihres USB-Speichers als USB-Massenspeicher ist ein Problem aufgetreten."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Bei der Verwendung Ihrer SD-Karte als USB-Massenspeicher ist ein Problem aufgetreten."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index bbd02f2..c74839f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Διαγραφή των δεδομένων του τηλεφώνου χωρίς προειδοποίηση με επαναφορά των εργοστασιακών δεδομένων"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ρύθμιση του γενικού διακομιστή μεσολάβησης της συσκευής"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ορίστε τη χρήση του γενικού διακομιστή μεσολάβησης της συσκευής όταν είναι ενεργοποιημένη η πολιτική. Μόνο ο διαχειριστής της πρώτης συσκευής ορίζει τον ισχύοντα γενικό διακομιστή μεσολάβησης."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Ορισμός λήξης κωδ. πρόσβασης"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Οικία"</item>
<item msgid="869923650527136615">"Κινητό"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ανάγνωση ιστορικού και σελιδοδεικτών προγράμματος περιήγησης"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Αποστέλλεται μεγάλος αριθμός μηνυμάτων SMS. Επιλέξτε \"OK\" για συνέχεια, ή \"Ακύρωση\" για διακοπή αποστολής."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Ακύρωση"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Ορισμός"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Προεπιλεγμένο"</string>
<string name="no_permissions" msgid="7283357728219338112">"Δεν απαιτούνται άδειες"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Εμφάνιση όλων"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Μαζική αποθήκευση USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Το USB είναι συνδεδεμένο"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Συνδέσατε το τηλέφωνό σας στον υπολογιστή μέσω USB. Επιλέξτε το παρακάτω κουμπί αν θέλετε να αντιγράψετε αρχεία μεταξύ του υπολογιστή και του χώρου αποθήκευσης USB του Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Συνδέσατε το τηλέφωνό σας στον υπολογιστή μέσω USB. Επιλέξτε το παρακάτω κουμπί αν θέλετε να αντιγράψετε αρχεία μεταξύ του υπολογιστή και του χώρου αποθήκευσης USB του Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Συνδεθήκατε στον υπολογιστή σας μέσω USB. Αγγίξτε το παρακάτω κουμπί, αν θέλετε να αντιγράψετε αρχεία ανάμεσα στον υπολογιστή σας και τον χώρο αποθήκευσης USB του Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Συνδεθήκατε στον υπολογιστή σας μέσω USB. Αγγίξτε το παρακάτω κουμπί, αν θέλετε να αντιγράψετε αρχεία ανάμεσα στον υπολογιστή σας και την κάρτα SD του Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Ενεργοποίηση αποθηκευτικού χώρου USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Παρουσιάστηκε ένα πρόβλημα στη χρήση του αποθηκευτικού χώρου USB ως χώρο USB μαζικής αποθήκευσης."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Παρουσιάστηκε ένα πρόβλημα στη χρήση της κάρτας SD ως χώρο USB μαζικής αποθήκευσης."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index eab891f..11ae9f4 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -905,6 +905,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"A large number of SMS messages are being sent. Select \"OK\" to continue or \"Cancel\" to stop sending."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancel"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Set"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
<string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 7fc79b1..abce7dd 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -481,10 +481,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Borrar los datos del teléfono sin advertencias al restablecer la configuración original"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Configura el proxy global de dispositivo"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Establecer la caducidad de la contraseña"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -867,6 +865,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Se envía una gran cantidad de mensajes SMS. Selecciona \"Aceptar\" para continuar o \"Cancelar\" para detener el envío."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Aceptar"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
<string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
@@ -874,8 +874,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Almacenamiento masivo USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"conectado al USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Has conectado tu teléfono a tu computadora mediante USB. Selecciona el botón a continuación si deseas copiar los archivos entre tu computadora y el almacenamiento USB de Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Has conectado tu teléfono a tu computadora mediante USB. Selecciona el botón a continuación si deseas copiar los archivos entre tu computadora y el almacenamiento USB de Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Has conectado tu teléfono a tu computadora mediante USB. Selecciona el botón a continuación si deseas copiar los archivos entre tu computadora y el almacenamiento USB de Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Has conectado tu teléfono a tu computadora mediante USB. Selecciona el botón a continuación si deseas copiar los archivos entre tu computadora y la tarjeta SD de Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar el almacenamiento USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Hay un problema para utilizar el almacenamiento USB en el almacenamiento masivo USB."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Hay un problema para utilizar tu tarjeta SD en el almacenamiento masivo USB."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 1b28dca..8c3543c 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Borrado de los datos del teléfono sin avisar restableciendo datos de fábrica"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir el servidor proxy global"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir caducidad contraseña"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Móvil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leer información de marcadores y del historial del navegador"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Se ha enviado un número elevado de mensajes SMS. Selecciona \"Aceptar\" para continuar o \"Cancelar\" para interrumpir el envío."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Aceptar"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
<string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Almacenamiento USB masivo"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Conectado por USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Has conectado el teléfono al equipo mediante USB. Selecciona el botón situado debajo si deseas copiar archivos entre el equipo y el almacenamiento USB del teléfono con Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Has conectado el teléfono al equipo mediante USB. Selecciona el botón situado debajo si deseas copiar archivos entre el equipo y el almacenamiento USB del teléfono con Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Has conectado el teléfono al equipo mediante USB. Toca el botón situado debajo si deseas copiar archivos entre el equipo y el almacenamiento USB del teléfono Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Has conectado el teléfono al equipo mediante USB. Toca el botón situado debajo si deseas copiar archivos entre el equipo y la tarjeta SD del teléfono Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar almacenamiento USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Se ha producido un problema al utilizar el almacenamiento USB para el almacenamiento masivo USB."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Se ha producido un problema al utilizar la tarjeta SD para el almacenamiento USB masivo."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index cbb5fe3..068bfe0 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"تعداد زیادی پیامک ارسال شده است. برای ادامه، \"تأیید\" را کلیک کرده و برای توقف ارسال، \"لغو\" را کلیک کنید."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"تأیید"</string>
<string name="sms_control_no" msgid="1715320703137199869">"لغو"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"تنظیم"</string>
<string name="default_permission_group" msgid="2690160991405646128">"پیش فرض"</string>
<string name="no_permissions" msgid="7283357728219338112">"مجوزی لازم نیست"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3390669..bddb852 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Olet lähettämässä suurta määrää tekstiviestejä. Jatka valitsemalla OK tai peruuta lähetys valitsemalla Peruuta."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Peruuta"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
<string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f618070..700674c 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Effacer les données du téléphone sans avertissement, en restaurant les valeurs d\'usine"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Définir le proxy global du mobile"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquez le proxy global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le proxy global utilisé."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Définir date exp. mot de passe"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domicile"</item>
<item msgid="869923650527136615">"Mobile"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lire l\'historique et les favoris du navigateur"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Vous êtes sur le point d\'envoyer un grand nombre de messages SMS. Sélectionnez OK pour continuer ou Annuler pour interrompre l\'envoi."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annuler"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Définir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Par défaut"</string>
<string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tout afficher"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Stockage de masse USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Connecté à l\'aide d\'un câble USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Vous avez connecté votre téléphone à votre ordinateur à l\'aide d\'un câble USB. Sélectionnez le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre Android, ou inversement."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Vous avez connecté votre téléphone à votre ordinateur à l\'aide d\'un câble USB. Sélectionnez le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre Android, ou inversement."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la mémoire de stockage USB de votre Android, ou inversement."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Vous êtes connecté à votre ordinateur via un câble USB. Appuyez sur le bouton ci-dessous pour copier des fichiers de votre ordinateur vers la carte SD de votre Android, ou inversement."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activer la mémoire de stockage USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Un problème est survenu lors de l\'utilisation de votre mémoire de stockage USB comme mémoire de stockage de masse."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Un problème est survenu lors de l\'utilisation de votre carte SD comme mémoire de stockage de masse USB."</string>
diff --git a/core/res/res/values-he/strings.xml b/core/res/res/values-he/strings.xml
index c5d945c..25074ea 100644
--- a/core/res/res/values-he/strings.xml
+++ b/core/res/res/values-he/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"מספר גדול של הודעות SMS נשלח. בחר \'אישור\' כדי להמשיך או \'ביטול\' כדי לעצור את השליחה."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"אישור"</string>
<string name="sms_control_no" msgid="1715320703137199869">"ביטול"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"הגדר"</string>
<string name="default_permission_group" msgid="2690160991405646128">"ברירת מחדל"</string>
<string name="no_permissions" msgid="7283357728219338112">"לא דרושים אישורים"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index bc6d451..a075566 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Šalje se velika količina SMS poruka. Odaberite \"U redu\" za nastavak, ili za prekid slanja odaberite \"Odustani\"."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"U redu"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Odustani"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 36aea65..3a4bf8d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Nagyszámú SMS-t kíván elküldeni. A folytatáshoz válassza az \"OK\", a küldés leállításához a \"Mégse\" lehetőséget."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Mégse"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string>
diff --git a/core/res/res/values-id/strings.xml b/core/res/res/values-id/strings.xml
index 2d07b33..aa243e0 100644
--- a/core/res/res/values-id/strings.xml
+++ b/core/res/res/values-id/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Sejumlah besar pesan SMS sedang dikirimkan. Pilih \"OK\" untuk melanjutkan, atau \"Batal\" untuk menghentikan pengiriman."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Batal"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Bawaan"</string>
<string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 238a748..0b74664 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Cancella i dati del telefono senza preavviso eseguendo un ripristino dati di fabbrica"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Imposta il proxy globale del dispositivo"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Imposta il proxy globale del dispositivo in modo da utilizzarlo mentre la norma è attiva. Il proxy globale effettivo è impostabile solo dal primo amministratore del dispositivo."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Imposta scadenza password"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Stabilisci la scadenza della password di blocco dello schermo"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Casa"</item>
<item msgid="869923650527136615">"Cellulare"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lettura cronologia e segnalibri del browser"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"È in corso l\'invio di numerosi SMS. Seleziona \"OK\" per continuare, oppure \"Annulla\" per interrompere l\'invio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annulla"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predefinito"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra tutto"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Archivio di massa USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB collegata"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Il telefono è stato collegato al computer tramite USB. Seleziona il pulsante sottostante se desideri copiare file tra il computer e l\'archivio USB di Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Il telefono è stato collegato al computer tramite USB. Seleziona il pulsante sottostante se desideri copiare file tra il computer e l\'archivio USB di Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Ti sei collegato al computer tramite USB. Tocca il pulsante sotto se desideri copiare file tra il computer e l\'archivio USB di Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Ti sei collegato al computer tramite USB. Tocca il pulsante sotto se desideri copiare file tra il computer e la scheda SD di Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Attiva archivio USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Problema di utilizzo dell\'archivio USB come archivio di massa USB."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Problema di utilizzo della scheda SD come archivio di massa USB."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 75d3722..e8bb57a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"警告せずにデータの初期化を実行して端末内のデータを消去します。"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"端末のグローバルプロキシを設定"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ポリシーが有効になっている場合は端末のグローバルプロキシが使用されるように設定します。有効なグローバルプロキシを設定できるのは最初のデバイス管理者だけです。"</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"パスワードの有効期限の設定"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"自宅"</item>
<item msgid="869923650527136615">"携帯"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">"、 "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ブラウザの履歴とブックマークを読み取る"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"大量のSMSメッセージを送信しようとしています。[OK]で送信、[キャンセル]で中止します。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"キャンセル"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
<string name="default_permission_group" msgid="2690160991405646128">"端末既定"</string>
<string name="no_permissions" msgid="7283357728219338112">"権限の許可は必要ありません"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"すべて表示"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USBマスストレージ"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB接続"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"携帯端末をUSBでパソコンに接続しています。パソコンとAndroidのUSBストレージの間でファイルをコピーするには、下のボタンを選択します。"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"携帯端末をUSBでパソコンに接続しています。パソコンとAndroidのUSBストレージの間でファイルをコピーするには、下のボタンを選択します。"</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"USBでパソコンに接続しています。パソコンとAndroidのUSBストレージ間でファイルをコピーするには下のボタンをタップします。"</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"USBでパソコンに接続しています。パソコンとAndroidのSDカード間でファイルをコピーするには下のボタンをタップします。"</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USBストレージをONにする"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"USBストレージをUSBマスストレージとして使用する際に問題が発生しました。"</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"USBをUSBマスストレージとして使用する際に問題が発生しました。"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1ed8492..ab873be 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"초기화를 수행하여 경고 없이 휴대전화 데이터를 지웁니다."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"기기 전체 프록시 설정"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"비밀번호 만료 설정"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"집"</item>
<item msgid="869923650527136615">"모바일"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"브라우저의 기록 및 북마크 읽기"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"여러 개의 SMS 메시지를 보내는 중입니다. 계속하려면 \'확인\'을 선택하고 전송을 중지하려면 \'취소\'를 선택하세요."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"확인"</string>
<string name="sms_control_no" msgid="1715320703137199869">"취소"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"설정"</string>
<string name="default_permission_group" msgid="2690160991405646128">"기본값"</string>
<string name="no_permissions" msgid="7283357728219338112">"권한 필요 없음"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"모두 표시"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB 대용량 저장소"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB 연결됨"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"USB를 통해 휴대전화를 컴퓨터에 연결했습니다. 컴퓨터와 Android의 USB 저장소 간에 파일을 복사하려면 아래의 버튼을 선택하세요."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"USB를 통해 휴대전화를 컴퓨터에 연결했습니다. 컴퓨터와 Android의 USB 저장소 간에 파일을 복사하려면 아래의 버튼을 선택하세요."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"USB를 통해 컴퓨터에 연결했습니다. 컴퓨터와 Android의 USB 저장소 간에 파일을 복사하려면 아래의 버튼을 터치하세요."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"USB를 통해 컴퓨터에 연결했습니다. 컴퓨터와 Android의 SD 카드 간에 파일을 복사하려면 아래의 버튼을 터치하세요."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB 저장소 사용"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"USB 대용량 저장소로 공유 저장용량을 사용하는 동안 문제가 발생했습니다."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"USB 대용량 저장소로 SD 카드를 사용하는 동안 문제가 발생했습니다."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 41d9fbd..c9059cb 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Siunčiama daug SMS pranešimų. Pasirinkite „Gerai“, jei norite tęsti, arba „Atšaukti“, jei norite sustabdyti siuntimą."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Gerai"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Atšaukti"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d706ed5..ee3def8 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Tiek sūtīts liels īsziņu skaits. Atlasiet Labi, lai turpinātu, vai Atcelt, lai apturētu sūtīšanu."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Labi"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Atcelt"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
<string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 96d9c32..a7e1879 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Tilbakestill telefonens data uten advarsel ved å utføre tilbakestilling til fabrikkstandard"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angi enhetens globale mellomtjener"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angir den globale mellomtjeneren på enheten som skal brukes når regelen er aktivert. Kun den opprinnelige administratoren av enheten kan angi den globale mellomtjeneren."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Angi utløpsdato for passordet"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hjemmenummer"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"lese nettleserens logg og bokmerker"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Et stort antall SMS-meldinger blir sendt. Velg «OK» for å fortsette, eller «Avbryt» for å avbryte sendingen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Avbryt"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-masselagring"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB koblet til"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har koblet telefonen til datamaskinen via USB. Velg knappen nedenfor hvis du vil kopiere filer mellom datamaskinen og USB-lagring for Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har koblet telefonen til datamaskinen via USB. Velg knappen nedenfor hvis du vil kopiere filer mellom datamaskinen og USB-lagring for Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har koblet telefonen til datamaskinen via USB. Trykk på knappen nedenfor hvis du vil kopiere filer mellom datamaskinen og Android-telefonens USB-lagring."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har koblet telefonen til datamaskinen via USB. Trykk på knappen nedenfor hvis du vil kopiere filer mellom datamaskinen og SD-kortet i Android-telefonen."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå på USB-lagring"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Det oppstod et problem under USB-lagring for USB-enheten."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Det oppstod et problem under SD-kortet for USB-enheten."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8998fba..3f4c7d4 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"De gegevens van de telefoon zonder waarschuwing wissen door de fabrieksinstellingen te herstellen"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Algemene proxy voor het apparaat instellen"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Stel de algemene proxy voor het apparaat in die moet worden gebruikt terwijl het beleid is geactiveerd. Alleen de eerste apparaatbeheerder stelt de algemene proxy in."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Verval wachtwoord instellen"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Thuis"</item>
<item msgid="869923650527136615">"Mobiel"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"browsergeschiedenis en bladwijzers lezen"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Er wordt een groot aantal SMS-berichten verzonden. Selecteer \'OK\' om door te gaan of \'Annuleren\' om de verzending te stoppen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Annuleren"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standaard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Alles weergeven"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-massaopslag"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-verbinding"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"U heeft uw telefoon via USB op uw computer aangesloten. Selecteer de onderstaande knop als u bestanden tussen uw computer en de USB-opslag van uw Android wilt kopiëren."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"U heeft uw telefoon via USB op uw computer aangesloten. Selecteer de onderstaande knop als u bestanden tussen uw computer en de USB-opslag van uw Android wilt kopiëren."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"U heeft uw telefoon via USB op uw computer aangesloten. Raak de onderstaande knop aan als u bestanden tussen uw computer en de USB-opslag van uw Android wilt kopiëren."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"U heeft uw telefoon via USB op uw computer aangesloten. Raak de onderstaande knop aan als u bestanden tussen uw computer en de SD-kaart van uw Android wilt kopiëren."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB-opslag inschakelen"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Er is een probleem bij het gebruik van uw USB-opslag voor USB-massaopslag."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Er is een probleem bij het gebruik van uw SD-kaart voor USB-massaopslag."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index ec80f83..fcd7275 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Wymazywanie danych z telefonu bez ostrzeżenia, przez przywrócenie danych fabrycznych"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ustaw globalny serwer proxy urządzenia"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ustaw globalny serwer proxy urządzenia do wykorzystywania przy włączonych zasadach. Tylko pierwszy administrator urządzenia ustawia obowiązujący globalny serwer proxy."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Ustaw wygasanie hasła"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Dom"</item>
<item msgid="869923650527136615">"Komórka"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"odczyt historii i zakładek przeglądarki"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Wysyłana jest duża liczba wiadomości SMS. Wybierz „OK”, aby kontynuować, lub „Anuluj”, aby zatrzymać wysyłanie."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Anuluj"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaż wszystko"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Pamięć masowa USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Połączenie przez USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Telefon został połączony z komputerem za pośrednictwem USB. Wybierz poniższy przycisk, aby skopiować pliki między komputerem a nośnikiem USB systemu Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Telefon został połączony z komputerem za pośrednictwem USB. Wybierz poniższy przycisk, aby skopiować pliki między komputerem a nośnikiem USB systemu Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Nawiązano połączenie z komputerem za pośrednictwem USB. Dotknij poniższego przycisku, aby skopiować pliki między komputerem a nośnikiem USB systemu Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Nawiązano połączenie z komputerem za pośrednictwem USB. Dotknij poniższego przycisku, aby skopiować pliki między komputerem a kartą SD systemu Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Włącz nośnik USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Wystąpił problem z użyciem nośnika USB jako pamięci masowej USB."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Wystąpił problem z użyciem karty SD jako nośnika pamięci masowej USB."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5e9b0a4..47a9ed7 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Apagar os dados do telefone sem avisar, ao efectuar uma reposição de dados de fábrica"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do aparelho"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir o proxy global do aparelho a ser utilizado quando a política estiver activada. Só o primeiro administrador do aparelho define o proxy global efectivo."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Def. valid. da palavra-passe"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residência"</item>
<item msgid="869923650527136615">"Móvel"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e marcadores do browser"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Está a ser enviado um grande número de mensagens SMS. Seleccione \"OK\" para continuar ou \"Cancelar\" para parar o envio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predefinido"</string>
<string name="no_permissions" msgid="7283357728219338112">"Não são necessárias permissões"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar tudo"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Armazenamento em massa USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Ligado através de USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Ligou o telemóvel ao computador através de USB. Seleccione o botão abaixo se pretender copiar ficheiros entre o computador e o armazenamento USB do Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Ligou o telemóvel ao computador através de USB. Seleccione o botão abaixo se pretender copiar ficheiros entre o computador e o armazenamento USB do Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Ligou ao computador através de USB. Toque no botão abaixo se pretender copiar ficheiros entre o computador e o armazenamento USB do Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Ligou ao computador através de USB. Toque no botão abaixo se pretender copiar ficheiros entre o computador e o cartão SD do Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar armazenamento USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Existe um problema ao utilizar o armazenamento USB para o armazenamento em massa USB."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Existe um problema ao utilizar o cartão SD para armazenamento em massa USB."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index ad8f64a..5aeb79f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Apaga os dados do telefone sem aviso, executando uma redefinição da configuração original"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir o proxy global do dispositivo"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir validade da senha"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Residencial"</item>
<item msgid="869923650527136615">"Celular"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ler histórico e favoritos do Navegador"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Muitas mensagens SMS estão sendo enviadas. Selecione \"OK\" para continuar ou \"Cancelar\" para interromper o envio."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Cancelar"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todas"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Armazenamento USB em massa"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Conectado por USB"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Você conectou o telefone ao computador via USB. Selecione o botão abaixo se quiser copiar arquivos entre seu computador e o armazenamento USB do Android."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Você conectou o telefone ao computador via USB. Selecione o botão abaixo se quiser copiar arquivos entre seu computador e o armazenamento USB do Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Você conectou ao computador via USB. Toque no botão abaixo se quiser copiar arquivos entre o computador e o armazenamento USB do seu Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Você conectou ao computador via USB. Toque no botão abaixo se quiser copiar arquivos entre o computador e o cartão SD do seu Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Ativar o armazenamento USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Há um problema com o uso do seu armazenamento USB para armazenamento USB em massa."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Há um problema com o uso do seu cartão SD para armazenamento USB em massa."</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 527e4e1..a1cbc4a 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -904,6 +904,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Vulais Vus trametter in grond dumber da messadis SMS? Tschernì OK per cuntinuar u Interrumper per annullar la spediziun."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Interrumper"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
<string name="no_permissions" msgid="7283357728219338112">"Naginas permissiuns obligatoricas"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 486591c..f235957 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"În acest moment se trimit multe mesaje SMS. Selectaţi „OK” pentru a continua sau „Anulaţi” pentru a opri trimiterea."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Anulaţi"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Prestabilit"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nu se solicită nicio permisiune"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 976a006..4e4bee8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Уничтожить все данные на телефоне без предупреждения путем сброса настроек"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Глобальный прокси-сервер"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Настройте глобальный прокси-сервер устройства, который будет использоваться при активной политике. Глобальный прокси-сервер должен настроить первый администратор устройства."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Задать время действия пароля"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Задать время действия пароля перед появлением экрана блокировки"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Домашний"</item>
<item msgid="869923650527136615">"Мобильный"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"считывать историю и закладки браузера"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Отправляется большое количество SMS-сообщений. Нажмите \"ОК\" для продолжения или \"Отмена\" для прекращения отправки."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"ОК"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Отмена"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Установить"</string>
<string name="default_permission_group" msgid="2690160991405646128">"По умолчанию"</string>
<string name="no_permissions" msgid="7283357728219338112">"Не требуется разрешений"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Показать все"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"Запоминающее устройство USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-подключение установлено"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Телефон подключен к компьютеру через порт USB. Для копирования файлов между компьютером и USB-накопителем Android нажмите кнопку ниже."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Телефон подключен к компьютеру через порт USB. Для копирования файлов между компьютером и USB-накопителем Android нажмите кнопку ниже."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Телефон подключен к компьютеру через порт USB. Нажмите приведенную ниже кнопку, чтобы скопировать файлы с компьютера на USB-накопитель устройства Android."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Телефон подключен к компьютеру через порт USB. Нажмите приведенную ниже кнопку, чтобы скопировать файлы с компьютера на SD-карту устройства Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Включить USB-накопитель"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"При использовании USB-накопителя в качестве запоминающего устройства USB возникла неполадка."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"При использовании SD-карты в качестве запоминающего устройства USB возникла неполадка."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 7e21ae5..d0413cf 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Odosiela sa veľký počet správ SMS. Ak chcete pokračovať, vyberte OK. Ak chcete odosielanie ukončiť, vyberte Zrušiť."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Zrušiť"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string>
<string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 68eb899..ddcc6e5 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"V pošiljanju je veliko sporočil SMS. Če želite nadaljevati, izberite »V redu«. Če želite pošiljanje ustaviti, izberite »Prekliči«."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"V redu"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Prekliči"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string>
<string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5cf7223..7287793 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Шаље се велики број SMS порука. Кликните на „Потврди“ да бисте наставили или на „Откажи“ да бисте зауставили слање."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Потврди"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Откажи"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Подеси"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Подразумевано"</string>
<string name="no_permissions" msgid="7283357728219338112">"Није потребна ниједна дозвола"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index e5de6ad..3ace2e3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Ta bort data från telefonen utan förvarning genom att återställa standardinställningarna"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ange global proxyserver"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ange vilken global proxyserver som ska användas när policyn är aktiverad. Endast den första enhetsadministratören anger den faktiska globala proxyservern."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Ange lösenordets utgångsdatum"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Hem"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"läsa webbläsarhistorik och bokmärken"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Flera SMS-meddelanden skickas. Tryck på OK om du vill fortsätta eller på Avbryt om du vill avsluta sändningen."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Avbryt"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standardinställning"</string>
<string name="no_permissions" msgid="7283357728219338112">"Inga behörigheter krävs"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Visa alla"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-masslagring"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB-ansluten"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har anslutit telefonen till datorn via USB. Välj knappen nedan om du vill kopiera filer mellan datorn och Android-telefonens USB-lagringsenhet."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har anslutit telefonen till datorn via USB. Välj knappen nedan om du vill kopiera filer mellan datorn och Android-telefonens USB-lagringsenhet."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Du har anslutit telefonen till datorn via USB. Tryck på knappen nedan om du vill kopiera filer mellan datorn och Android-telefonens USB-lagringsenhet."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Du har anslutit telefonen till datorn via USB. Tryck på knappen nedan om du vill kopiera filer mellan datorn och SD-kortet i din Android."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Aktivera USB-lagring"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Det gick inte att använda din USB-lagringsenhet för USB-masslagring."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Det gick inte att använda ditt SD-kort för USB-masslagring."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0113275..d1adc6a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"กำลังส่งข้อความ SMS จำนวนมาก เลือก \"ตกลง\" เพื่อทำงานต่อหรือ \"ยกเลิก\" เพื่อหยุดส่ง"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"ตกลง"</string>
<string name="sms_control_no" msgid="1715320703137199869">"ยกเลิก"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"ตั้งค่า"</string>
<string name="default_permission_group" msgid="2690160991405646128">"เริ่มต้น"</string>
<string name="no_permissions" msgid="7283357728219338112">"ไม่ต้องการการอนุญาต"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0e28a1a..209b4b2 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Pinapadala ang malaking bilang ng mga SMS na mensahe. Piliin ang \"OK\" upang magpatuloy, o \"Kanselahin\" upang itigil ang pagpapadala."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Kanselahin"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
<string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index a1abbeb..d24df0c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Fabrika verilerine sıfırlama işlemi gerçekleştirerek telefondaki verileri uyarıda bulunmadan silin"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Cihaz genelinde geçerli proxy\'i ayarla"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Politika etkin olduğunda kullanılacak cihaz genelinde geçerli proxy\'yi ayarlayın. Etkin genel proxy\'yi yalnızca ilk cihaz yöneticisi ayarlar."</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"Şifre süre sonu tarihi ayarla"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Ev"</item>
<item msgid="869923650527136615">"Mobil"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"Tarayıcı geçmişini ve favorileri oku"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Çok sayıda SMS mesajı gönderiliyor. Devam etmek için \"Tamam\"ı, göndermeyi durdurmak için \"İptal\"i seçin."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"Tamam"</string>
<string name="sms_control_no" msgid="1715320703137199869">"İptal"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Varsayılan"</string>
<string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tümünü göster"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB Yığın Depolama"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB bağlandı"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Telefonunuzu USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB depolama birimi arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeyi seçin."</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Telefonunuzu USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB depolama birimi arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeyi seçin."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB depolama birimi arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin SD kartı arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"USB depolama birimini aç"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"USB depolama biriminizi USB yığın depolama amaçlı kullanmayla ilgili bir sorun var."</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"SD kartınızı USB yığın dep br amaçlı kullanmada sorun var."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f9eacb9..a029694 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Надсил-ся завелика к-сть SMS повідомл. Натисн. \"OK\", щоб продовж, або \"Скасувати\", щоб припин. надсил."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Скасувати"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Устан."</string>
<string name="default_permission_group" msgid="2690160991405646128">"За умовч."</string>
<string name="no_permissions" msgid="7283357728219338112">"Дозвіл не потрібний"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e33b7be..9c61058 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -925,6 +925,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"Một số lượng lớn các tin nhắn SMS đang được gửi. Chọn \"OK\" để tiếp tục hoặc \"Huỷ\" để dừng gửi."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Huỷ"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
<string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 031d488..e67e102 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"恢复出厂设置时,将擦除手机上的数据而不发送警告"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"设置设备全局代理"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"请设置在启用政策的情况下要使用的设备全局代理。只有第一设备管理员才可设置有效的全局代理。"</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"设置密码有效期"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制屏幕锁定密码的使用期限"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住宅"</item>
<item msgid="869923650527136615">"手机"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"读取浏览器的历史记录和书签"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"正在发送大量短信。选择“确定”继续,或选择“取消”停止发送。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"确定"</string>
<string name="sms_control_no" msgid="1715320703137199869">"取消"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"设置"</string>
<string name="default_permission_group" msgid="2690160991405646128">"默认"</string>
<string name="no_permissions" msgid="7283357728219338112">"不需要任何权限"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"全部显示"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB 大容量存储设备"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB 已连接"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"您已通过 USB 将手机连接至计算机。如果您要在计算机与 Android 手机的 USB 存储设备之间复制文件,请点击下面的按钮。"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"您已通过 USB 将手机连接至计算机。如果您要在计算机与 Android 手机的 USB 存储设备之间复制文件,请点击下面的按钮。"</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"您已通过 USB 连接至计算机。如果您要在计算机与 Android 设备的 USB 存储设备之间复制文件,请触摸下面的按钮。"</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"您已通过 USB 连接至计算机。如果您要在计算机和 Android 设备的 SD 卡之间复制文件,请触摸下面的按钮。"</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"打开 USB 存储设备"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"使用 USB 存储设备作为 USB 大容量存储设备时出现问题。"</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"使用 SD 卡作为 USB 大容量存储设备时出现问题。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c7cfe8e..bab4dfb 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -482,10 +482,8 @@
<string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"執行重設為原廠設定時,系統會直接清除手機資料而不提出警告"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"設定裝置全域 Proxy"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域 Proxy,只有第一個裝置管理員所設定的全域 Proxy 具有效力。"</string>
- <!-- no translation found for policylab_expirePassword (2314569545488269564) -->
- <skip />
- <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
- <skip />
+ <string name="policylab_expirePassword" msgid="2314569545488269564">"設定密碼到期日"</string>
+ <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制螢幕鎖定密碼的使用期限"</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"住家電話"</item>
<item msgid="869923650527136615">"行動電話"</item>
@@ -668,8 +666,7 @@
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
<skip />
- <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
- <skip />
+ <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"讀取瀏覽器的記錄與書籤"</string>
@@ -869,6 +866,8 @@
<string name="sms_control_message" msgid="1289331457999236205">"即將傳送大量 SMS 簡訊。選取 [確定] 繼續或 [取消] 停止傳送。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"確定"</string>
<string name="sms_control_no" msgid="1715320703137199869">"取消"</string>
+ <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+ <skip />
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
<string name="default_permission_group" msgid="2690160991405646128">"預設值"</string>
<string name="no_permissions" msgid="7283357728219338112">"無須許可"</string>
@@ -876,8 +875,8 @@
<string name="perms_show_all" msgid="2671791163933091180"><b>"顯示全部"</b></string>
<string name="usb_storage_activity_title" msgid="2399289999608900443">"USB 大量儲存裝置"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB 已連接"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"已透過 USB 連接手機與電腦。如要在電腦和 Android 的 USB 儲存裝置之間複製檔案,請選取下方按鈕。"</string>
- <!-- outdated translation 115779324551502062 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"已透過 USB 連接手機與電腦。如要在電腦和 Android 的 USB 儲存裝置之間複製檔案,請選取下方按鈕。"</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"您已透過 USB 與電腦建立連線。如要在電腦和 Android 的 USB 儲存裝置之間複製檔案,請輕觸下方按鈕。"</string>
+ <string name="usb_storage_message" product="default" msgid="4510858346516069238">"您已透過 USB 與電腦建立連線。如要在電腦和 Android 的 SD 卡之間複製檔案,請輕觸下方按鈕。"</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"開啟 USB 儲存裝置"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"使用您的 USB 儲存裝置作為 USB 大量儲存裝置時發生問題。"</string>
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"使用您的 SD 卡作為 USB 大量儲存裝置時發生問題。"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a911e8d..78465cf 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -602,9 +602,12 @@
<!-- Theme to use for alert dialogs spawned from this theme. -->
<attr name="alertDialogTheme" format="reference" />
- <!-- Drawable to use for vertical dividers. -->
+ <!-- Drawable to use for generic vertical dividers. -->
<attr name="dividerVertical" format="reference" />
+ <!-- Drawable to use for generic horizontal dividers. -->
+ <attr name="dividerHorizontal" format="reference" />
+
<!-- Style for button groups -->
<attr name="buttonGroupStyle" format="reference" />
@@ -614,6 +617,9 @@
<!-- Background drawable for standalone items that need focus/pressed states. -->
<attr name="selectableItemBackground" format="reference" />
+ <!-- Style for buttons without an explicit border, often used in groups. -->
+ <attr name="borderlessButtonStyle" format="reference" />
+
<!-- ============================ -->
<!-- SearchView styles and assets -->
<!-- ============================ -->
@@ -1293,6 +1299,11 @@
<attr name="bottomBright" format="reference|color" />
<attr name="bottomMedium" format="reference|color" />
<attr name="centerMedium" format="reference|color" />
+ <attr name="layout" />
+ <attr name="listLayout" format="reference" />
+ <attr name="multiChoiceItemLayout" format="reference" />
+ <attr name="singleChoiceItemLayout" format="reference" />
+ <attr name="listItemLayout" format="reference" />
</declare-styleable>
<!-- Fragment animation class attributes. -->
@@ -2178,6 +2189,17 @@
the minimum size of the largest child. If false, all children are
measured normally. -->
<attr name="measureWithLargestChild" format="boolean" />
+ <!-- Drawable to use as a vertical divider between buttons. -->
+ <attr name="divider" />
+ <!-- Setting for which dividers to show. -->
+ <attr name="showDividers">
+ <flag name="none" value="0" />
+ <flag name="beginning" value="1" />
+ <flag name="middle" value="2" />
+ <flag name="end" value="4" />
+ </attr>
+ <!-- Size of padding on either end of a divider. -->
+ <attr name="dividerPadding" format="dimension" />
</declare-styleable>
<declare-styleable name="ListView">
<!-- Reference to an array resource that will populate the ListView. For static content,
@@ -4547,11 +4569,7 @@
<!-- Drawable to use as a background for buttons added to this group. -->
<attr name="buttonBackground" format="reference" />
<!-- Setting for which dividers to show. -->
- <attr name="showDividers">
- <flag name="beginning" value="1" />
- <flag name="middle" value="2" />
- <flag name="end" value="4" />
- </attr>
+ <attr name="showDividers" />
</declare-styleable>
<declare-styleable name="ActionBar_LayoutParams">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e1460e1..3fac653 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1392,6 +1392,10 @@
<public type="attr" name="rotation"/>
<public type="attr" name="rotationX"/>
<public type="attr" name="rotationY"/>
+ <public type="attr" name="showDividers" />
+ <public type="attr" name="dividerPadding" />
+ <public type="attr" name="borderlessButtonStyle" />
+ <public type="attr" name="dividerHorizontal" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
@@ -1555,6 +1559,7 @@
<public type="style" name="Widget.Holo.Light.ActionMode" />
<public type="style" name="Widget.Holo.Light.ActionButton.CloseMode" />
<public type="style" name="Widget.Holo.Light.ActionBar" />
+ <public type="style" name="Widget.Holo.Button.Borderless" />
<public type="string" name="selectTextMode" />
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f5f392d..b7c11a8 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1060,7 +1060,6 @@
</style>
<style name="TextAppearance.Holo.Medium" parent="TextAppearance.Medium">
- <item name="android:textLineHeight">24dip</item>
</style>
<style name="TextAppearance.Holo.Small" parent="TextAppearance.Small">
@@ -1304,6 +1303,10 @@
<item name="android:paddingBottom">4dip</item>
</style>
+ <style name="Widget.Holo.Button.Borderless">
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ </style>
+
<style name="Widget.Holo.Button.Small">
<item name="android:background">@android:drawable/btn_default_holo_dark</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
@@ -1333,7 +1336,7 @@
<style name="Widget.Holo.ButtonGroup" parent="Widget.ButtonGroup">
<item name="divider">?android:attr/dividerVertical</item>
<item name="showDividers">middle</item>
- <item name="android:background">@android:drawable/btn_default_holo_dark</item>
+ <item name="dividerPadding">8dip</item>
</style>
<style name="Widget.Holo.ButtonGroup.AlertDialog">
@@ -1701,7 +1704,7 @@
<style name="Widget.Holo.Light.ListView.DropDown">
</style>
- <style name="Widget.Holo.Light.EditText" parent="Widget.EditText">
+ <style name="Widget.Holo.Light.EditText" parent="Widget.Holo.EditText">
</style>
<style name="Widget.Holo.Light.ExpandableListView" parent="Widget.ExpandableListView">
@@ -1924,6 +1927,11 @@
<item name="bottomBright">@android:drawable/dialog_bottom_holo_dark</item>
<item name="bottomMedium">@android:drawable/dialog_bottom_holo_dark</item>
<item name="centerMedium">@android:drawable/dialog_middle_holo_dark</item>
+ <item name="layout">@android:layout/alert_dialog_holo</item>
+ <item name="listLayout">@android:layout/select_dialog_holo</item>
+ <item name="listItemLayout">@android:layout/select_dialog_item_holo</item>
+ <item name="multiChoiceItemLayout">@android:layout/select_dialog_multichoice_holo</item>
+ <item name="singleChoiceItemLayout">@android:layout/select_dialog_singlechoice_holo</item>
</style>
<style name="AlertDialog.Holo.Light">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index e1040d9..8c59360 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -92,6 +92,7 @@
<item name="groupButtonBackground">@null</item>
<item name="selectableItemBackground">@android:drawable/item_background</item>
+ <item name="borderlessButtonStyle">?android:attr/buttonStyle</item>
<item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item>
<!-- List attributes -->
@@ -258,6 +259,7 @@
<item name="actionBarSize">56dip</item>
<item name="dividerVertical">@drawable/divider_vertical_dark</item>
+ <item name="dividerHorizontal">@drawable/divider_vertical_dark</item>
<item name="buttonGroupStyle">@android:style/Widget.ButtonGroup</item>
<!-- SearchView attributes -->
@@ -723,6 +725,7 @@
<item name="groupButtonBackground">@android:drawable/group_button_background_holo_dark</item>
<item name="selectableItemBackground">@android:drawable/item_background_holo_dark</item>
+ <item name="borderlessButtonStyle">@android:style/Widget.Holo.Button.Borderless</item>
<item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item>
<!-- List attributes -->
@@ -883,6 +886,7 @@
<item name="actionBarSize">56dip</item>
<item name="dividerVertical">@drawable/divider_vertical_holo_dark</item>
+ <item name="dividerHorizontal">@drawable/divider_vertical_holo_dark</item>
<item name="buttonGroupStyle">@android:style/Widget.Holo.ButtonGroup</item>
<!-- SearchView attributes -->
@@ -1046,20 +1050,20 @@
<item name="textSelectHandleWindowStyle">@android:style/Widget.Holo.TextSelectHandle</item>
<!-- Widget styles -->
- <item name="absListViewStyle">@android:style/Widget.Holo.AbsListView</item>
+ <item name="absListViewStyle">@android:style/Widget.Holo.Light.AbsListView</item>
<item name="autoCompleteTextViewStyle">@android:style/Widget.Holo.Light.AutoCompleteTextView</item>
- <item name="checkboxStyle">@android:style/Widget.Holo.CompoundButton.CheckBox</item>
+ <item name="checkboxStyle">@android:style/Widget.Holo.Light.CompoundButton.CheckBox</item>
<item name="dropDownListViewStyle">@android:style/Widget.Holo.ListView.DropDown</item>
- <item name="editTextStyle">@android:style/Widget.Holo.EditText</item>
- <item name="expandableListViewStyle">@android:style/Widget.Holo.ExpandableListView</item>
- <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.ExpandableListView.White</item>
- <item name="galleryStyle">@android:style/Widget.Holo.Gallery</item>
- <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.GestureOverlayView</item>
- <item name="gridViewStyle">@android:style/Widget.Holo.GridView</item>
- <item name="imageButtonStyle">@android:style/Widget.Holo.ImageButton</item>
- <item name="imageWellStyle">@android:style/Widget.Holo.ImageWell</item>
- <item name="listViewStyle">@android:style/Widget.Holo.ListView</item>
- <item name="listViewWhiteStyle">@android:style/Widget.Holo.ListView.White</item>
+ <item name="editTextStyle">@android:style/Widget.Holo.Light.EditText</item>
+ <item name="expandableListViewStyle">@android:style/Widget.Holo.Light.ExpandableListView</item>
+ <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.Light.ExpandableListView.White</item>
+ <item name="galleryStyle">@android:style/Widget.Holo.Light.Gallery</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.Light.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.Holo.Light.GridView</item>
+ <item name="imageButtonStyle">@android:style/Widget.Holo.Light.ImageButton</item>
+ <item name="imageWellStyle">@android:style/Widget.Holo.Light.ImageWell</item>
+ <item name="listViewStyle">@android:style/Widget.Holo.Light.ListView</item>
+ <item name="listViewWhiteStyle">@android:style/Widget.Holo.Light.ListView.White</item>
<item name="popupWindowStyle">@android:style/Widget.Holo.Light.PopupWindow</item>
<item name="progressBarStyle">@android:style/Widget.Holo.Light.ProgressBar</item>
<item name="progressBarStyleHorizontal">@android:style/Widget.Holo.Light.ProgressBar.Horizontal</item>
@@ -1069,22 +1073,22 @@
<item name="progressBarStyleInverse">@android:style/Widget.Holo.Light.ProgressBar.Inverse</item>
<item name="progressBarStyleSmallInverse">@android:style/Widget.Holo.Light.ProgressBar.Small.Inverse</item>
<item name="progressBarStyleLargeInverse">@android:style/Widget.Holo.Light.ProgressBar.Large.Inverse</item>
- <item name="seekBarStyle">@android:style/Widget.Holo.SeekBar</item>
- <item name="ratingBarStyle">@android:style/Widget.Holo.RatingBar</item>
- <item name="ratingBarStyleIndicator">@android:style/Widget.Holo.RatingBar.Indicator</item>
- <item name="ratingBarStyleSmall">@android:style/Widget.Holo.RatingBar.Small</item>
- <item name="radioButtonStyle">@android:style/Widget.Holo.CompoundButton.RadioButton</item>
- <item name="scrollViewStyle">@android:style/Widget.Holo.ScrollView</item>
- <item name="horizontalScrollViewStyle">@android:style/Widget.Holo.HorizontalScrollView</item>
+ <item name="seekBarStyle">@android:style/Widget.Holo.Light.SeekBar</item>
+ <item name="ratingBarStyle">@android:style/Widget.Holo.Light.RatingBar</item>
+ <item name="ratingBarStyleIndicator">@android:style/Widget.Holo.Light.RatingBar.Indicator</item>
+ <item name="ratingBarStyleSmall">@android:style/Widget.Holo.Light.RatingBar.Small</item>
+ <item name="radioButtonStyle">@android:style/Widget.Holo.Light.CompoundButton.RadioButton</item>
+ <item name="scrollViewStyle">@android:style/Widget.Holo.Light.ScrollView</item>
+ <item name="horizontalScrollViewStyle">@android:style/Widget.Holo.Light.HorizontalScrollView</item>
<item name="spinnerStyle">?android:attr/dropDownSpinnerStyle</item>
<item name="dropDownSpinnerStyle">@android:style/Widget.Holo.Light.Spinner.DropDown</item>
- <item name="starStyle">@android:style/Widget.Holo.CompoundButton.Star</item>
- <item name="tabWidgetStyle">@android:style/Widget.Holo.TabWidget</item>
- <item name="textViewStyle">@android:style/Widget.Holo.TextView</item>
- <item name="webTextViewStyle">@android:style/Widget.Holo.WebTextView</item>
- <item name="webViewStyle">@android:style/Widget.Holo.WebView</item>
- <item name="dropDownItemStyle">@android:style/Widget.Holo.DropDownItem</item>
- <item name="spinnerDropDownItemStyle">@android:style/Widget.Holo.DropDownItem.Spinner</item>
+ <item name="starStyle">@android:style/Widget.Holo.Light.CompoundButton.Star</item>
+ <item name="tabWidgetStyle">@android:style/Widget.Holo.Light.TabWidget</item>
+ <item name="textViewStyle">@android:style/Widget.Holo.Light.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.Holo.Light.WebTextView</item>
+ <item name="webViewStyle">@android:style/Widget.Holo.Light.WebView</item>
+ <item name="dropDownItemStyle">@android:style/Widget.Holo.Light.DropDownItem</item>
+ <item name="spinnerDropDownItemStyle">@android:style/Widget.Holo.Light.DropDownItem.Spinner</item>
<item name="spinnerItemStyle">@android:style/Widget.Holo.TextView.SpinnerItem</item>
<item name="dropDownHintAppearance">@android:style/TextAppearance.Holo.Widget.DropDownHint</item>
<item name="keyboardViewStyle">@android:style/Widget.Holo.KeyboardView</item>
@@ -1128,6 +1132,7 @@
<item name="actionBarSize">56dip</item>
<item name="dividerVertical">@drawable/divider_vertical_holo_light</item>
+ <item name="dividerHorizontal">@drawable/divider_vertical_holo_light</item>
<item name="buttonGroupStyle">@android:style/Widget.Holo.Light.ButtonGroup</item>
<!-- SearchView attributes -->
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index c8ad60d..b878aa5 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -732,4 +732,20 @@
assertEquals(1, names.size());
assertEquals("foo", names.iterator().next());
}
+
+ /**
+ * Query parameters may omit the '='. http://b/3124097
+ */
+ public void testGetQueryParametersEmptyValue() {
+ assertEquals(Arrays.asList(""),
+ Uri.parse("http://foo/path?abc").getQueryParameters("abc"));
+ assertEquals(Arrays.asList(""),
+ Uri.parse("http://foo/path?foo=bar&abc").getQueryParameters("abc"));
+ assertEquals(Arrays.asList(""),
+ Uri.parse("http://foo/path?abcd=abc&abc").getQueryParameters("abc"));
+ assertEquals(Arrays.asList("a", "", ""),
+ Uri.parse("http://foo/path?abc=a&abc=&abc").getQueryParameters("abc"));
+ assertEquals(Arrays.asList("a", "", ""),
+ Uri.parse("http://foo/path?abc=a&abc=&abc=").getQueryParameters("abc"));
+ }
}
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index c3d3482f..44d75c1 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -455,7 +455,7 @@
<ol>
<li>Create a {@link android.widget.SpinnerAdapter} that provides the
list of selectable items for the list and the layout to use when drawing each item in the list.</li>
- <li>Implement {@link android.app.ActionBar.NavigationCallback} to define the behavior when the
+ <li>Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior when the
user selects an item from the list.</li>
<li>Turn on navigation mode for the Action Bar with {@link
android.app.ActionBar#setNavigationMode setNavigationMode()}. For example:
@@ -472,17 +472,17 @@
actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
</pre>
<p>This method takes your {@link android.widget.SpinnerAdapter} and {@link
-android.app.ActionBar.NavigationCallback}. More about these next.</p>
+android.app.ActionBar.OnNavigationListener}. More about these next.</p>
</li>
</ol>
<p>That's the basic setup. The {@link android.widget.SpinnerAdapter} and {@link
-android.app.ActionBar.NavigationCallback} is where most of the work is done. There are many ways
+android.app.ActionBar.OnNavigationListener} is where most of the work is done. There are many ways
you can implement these to define the functionality for your drop-down navigation. Implementing
various types of {@link android.widget.SpinnerAdapter} is beyond the scope of this
document—you should refer to the class refrence for more information about implementing it or
extending an existing implementation. However, below is a simple example for a {@link
-android.widget.SpinnerAdapter} and {@link android.app.ActionBar.NavigationCallback} to get you
+android.widget.SpinnerAdapter} and {@link android.app.ActionBar.OnNavigationListener} to get you
started.</p>
@@ -520,24 +520,24 @@
</pre>
-<h3 id="NavigationCallback">Example: simple NavigationCallback</h3>
+<h3 id="OnNavigationListener">Example: simple OnNavigationListener</h3>
-<p>Your implementation of {@link android.app.ActionBar.NavigationCallback} is where you handle
+<p>Your implementation of {@link android.app.ActionBar.OnNavigationListener} is where you handle
fragment changes or other modifications to your activity when the user selects an item from the
drop-down list. There's only one callback method to implement: {@link
-android.app.ActionBar.NavigationCallback#onNavigationItemSelected onNavigationItemSelected()}.</p>
+android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}.</p>
<p>The {@link
-android.app.ActionBar.NavigationCallback#onNavigationItemSelected onNavigationItemSelected()}
+android.app.ActionBar.OnNavigationListener#onNavigationItemSelected onNavigationItemSelected()}
method receives the position of the item in the list and an item ID provided by the {@link
android.widget.SpinnerAdapter}.</p>
<p>Here's an example that instantiates an anonymous implementation of {@link
-android.app.ActionBar.NavigationCallback}, which inserts a {@link android.app.Fragment} into the
+android.app.ActionBar.OnNavigationListener}, which inserts a {@link android.app.Fragment} into the
layout container identified by {@code R.id.fragment_container}:</p>
<pre>
-mNavigationCallback = new NavigationCallback() {
+mOnNavigationListener = new OnNavigationListener() {
// Get the same strings provided for the drop-down's ArrayAdapter
String[] strings = getResources().getStringArray(R.array.action_list);
@@ -556,7 +556,7 @@
};
</pre>
-<p>This instance of {@link android.app.ActionBar.NavigationCallback} can be given to {@link
+<p>This instance of {@link android.app.ActionBar.OnNavigationListener} can be given to {@link
android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}, in step 4 from
above.</p>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index cef057e..7416764 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,9 +52,8 @@
<div class="dashboard-panel">
<img alt="" height="250" width="460"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:7.9,15.0,0.1,40.8,36.2&chl=
-Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b,
-6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:6.3,10.6,0.1,39.6,43.4&chl
+=Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b,6fad0c" />
<table>
<tr>
@@ -62,13 +61,13 @@
<th>API Level</th>
<th>Distribution</th>
</tr>
-<tr><td>Android 1.5</td><td>3</td><td>7.9%</td></tr>
-<tr><td>Android 1.6</td><td>4</td><td>15.0%</td></tr>
-<tr><td>Android 2.1</td><td>7</td><td>40.8%</td></tr>
-<tr><td>Android 2.2</td><td>8</td><td>36.2%</td></tr>
+<tr><td>Android 1.5</td><td>3</td><td>6.3%</td></tr>
+<tr><td>Android 1.6</td><td>4</td><td>10.6%</td></tr>
+<tr><td>Android 2.1</td><td>7</td><td>39.6%</td></tr>
+<tr><td>Android 2.2</td><td>8</td><td>43.4%</td></tr>
</table>
-<p><em>Data collected during two weeks ending on November 1, 2010</em></p>
+<p><em>Data collected during two weeks ending on December 1, 2010</em></p>
<p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
</div><!-- end dashboard-panel -->
@@ -97,17 +96,16 @@
<img alt="" height="250" width="660" style="padding:5px;background:#fff"
src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,y,r&chxr=0,0,12|1,0,100|2,0,100&
-chxl=0%3A%7C2010/05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/
-01%7C10/15%7C2010/11/01%7C1%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C2%3A%7C0%25%7C25%25%7C50%25
-%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:98.9,99.3,100.3,100.8,99.7,99.
-8,99.8,99.7,99.8,99.9,99.9,99.9,99.9|61.6,63.1,72.7,76.1,78.4,80.9,84.3,86.5,87.9,89.2,90.2,91.1,92.
-0|32.0,34.9,45.9,51.0,54.9,58.8,64.0,68.1,70.3,72.1,73.8,75.3,77.0|0.0,0.0,0.8,1.2,1.8,3.3,4.3,11.3,
-27.8,32.1,33.4,34.5,36.2&chm=tAndroid%201.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid%201.6,
-5b831d,1,0,15,,t::-5|b,aadb5e,1,2,0|tAndroid%202.1,38540b,2,0,15,,t::-5|b,91da1e,2,3,0|tAndroid%202.
-2,131d02,3,7,15,,t::-5|B,6fad0c,3,4,0&chg=7,25&chdl=Android%201.5|Android%201.6|Android%202.1|
-Android%202.2&chco=add274,94d134,73ad18,507d08" />
+chxl=0:|2010/06/01|06/15|07/01|07/15|08/01|08/15|09/01|09/15|10/01|10/15|11/01|11/15|2010/12/01|1:|0
+%25|25%25|50%25|75%25|100%25|2:|0%25|25%25|50%25|75%25|100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&
+chxtc=0,5&chd=t:100.3,100.8,99.7,99.8,99.8,99.7,99.8,99.9,99.9,99.9,99.9,99.9,99.9|72.7,76.1,78.4,80
+.9,84.3,86.5,87.9,89.2,90.2,91.1,92.0,92.7,93.6|45.9,51.0,54.9,58.8,64.0,68.1,70.3,72.1,73.8,75.3,77
+.0,79.0,83.0|0.8,1.2,1.8,3.3,4.3,11.3,27.8,32.1,33.4,34.5,36.2,38.3,43.4&chm=tAndroid%201.5,7caa36,0
+,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid%201.6,5b831d,1,0,15,,t::-5|b,aadb5e,1,2,0|tAndroid%202.1,38540b
+,2,0,15,,t::-5|b,91da1e,2,3,0|tAndroid%202.2,131d02,3,5,15,,t::-5|B,6fad0c,3,4,0&chg=7,25&chdl=
+Android%201.5|Android%201.6|Android%202.1|Android%202.2&chco=add274,94d134,73ad18,507d08" />
-<p><em>Last historical dataset collected during two weeks ending on November 1, 2010</em></p>
+<p><em>Last historical dataset collected during two weeks ending on December 1, 2010</em></p>
</div><!-- end dashboard-panel -->
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 69b872b..e17a640 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -992,7 +992,12 @@
private boolean inScanDirectory(String path, String[] directories) {
for (int i = 0; i < directories.length; i++) {
- if (path.startsWith(directories[i])) {
+ String directory = directories[i];
+ if (mExternalStoragePath != null && directory.equals(mMediaStoragePath)) {
+ // database paths use external storage prefix
+ directory = mExternalStoragePath;
+ }
+ if (path.startsWith(directory)) {
return true;
}
}
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 0387989..139a6ea 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -33,6 +33,7 @@
import android.util.Log;
import java.io.File;
+import java.util.HashMap;
/**
* {@hide}
@@ -48,6 +49,14 @@
private final String mMediaStoragePath;
private final String mExternalStoragePath;
+ // cached property groups for single properties
+ private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByProperty
+ = new HashMap<Integer, MtpPropertyGroup>();
+
+ // cached property groups for all properties for a given format
+ private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByFormat
+ = new HashMap<Integer, MtpPropertyGroup>();
+
// true if the database has been modified in the current MTP session
private boolean mDatabaseModified;
@@ -386,6 +395,43 @@
MtpConstants.PROPERTY_DESCRIPTION,
};
+ static final int[] ALL_PROPERTIES = {
+ // NOTE must match FILE_PROPERTIES above
+ MtpConstants.PROPERTY_STORAGE_ID,
+ MtpConstants.PROPERTY_OBJECT_FORMAT,
+ MtpConstants.PROPERTY_PROTECTION_STATUS,
+ MtpConstants.PROPERTY_OBJECT_SIZE,
+ MtpConstants.PROPERTY_OBJECT_FILE_NAME,
+ MtpConstants.PROPERTY_DATE_MODIFIED,
+ MtpConstants.PROPERTY_PARENT_OBJECT,
+ MtpConstants.PROPERTY_PERSISTENT_UID,
+ MtpConstants.PROPERTY_NAME,
+ MtpConstants.PROPERTY_DISPLAY_NAME,
+ MtpConstants.PROPERTY_DATE_ADDED,
+
+ // image specific properties
+ MtpConstants.PROPERTY_DESCRIPTION,
+
+ // audio specific properties
+ MtpConstants.PROPERTY_ARTIST,
+ MtpConstants.PROPERTY_ALBUM_NAME,
+ MtpConstants.PROPERTY_ALBUM_ARTIST,
+ MtpConstants.PROPERTY_TRACK,
+ MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE,
+ MtpConstants.PROPERTY_DURATION,
+ MtpConstants.PROPERTY_GENRE,
+ MtpConstants.PROPERTY_COMPOSER,
+
+ // video specific properties
+ MtpConstants.PROPERTY_ARTIST,
+ MtpConstants.PROPERTY_ALBUM_NAME,
+ MtpConstants.PROPERTY_DURATION,
+ MtpConstants.PROPERTY_DESCRIPTION,
+
+ // image specific properties
+ MtpConstants.PROPERTY_DESCRIPTION,
+ };
+
private int[] getSupportedObjectProperties(int format) {
switch (format) {
case MtpConstants.FORMAT_MP3:
@@ -403,6 +449,8 @@
case MtpConstants.FORMAT_PNG:
case MtpConstants.FORMAT_BMP:
return IMAGE_PROPERTIES;
+ case 0:
+ return ALL_PROPERTIES;
default:
return FILE_PROPERTIES;
}
@@ -415,324 +463,32 @@
};
}
- private String queryString(int id, String column) {
- Cursor c = null;
- try {
- // for now we are only reading properties from the "objects" table
- c = mMediaProvider.query(mObjectsUri,
- new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
- if (c != null && c.moveToNext()) {
- return c.getString(1);
- } else {
- return "";
- }
- } catch (Exception e) {
- return null;
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
- private String queryAudio(int id, String column) {
- Cursor c = null;
- try {
- c = mMediaProvider.query(Audio.Media.getContentUri(mVolumeName),
- new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
- if (c != null && c.moveToNext()) {
- return c.getString(1);
- } else {
- return "";
- }
- } catch (Exception e) {
- return null;
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
- private String queryGenre(int id) {
- Cursor c = null;
- try {
- Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
- c = mMediaProvider.query(uri,
- new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
- null, null, null);
- if (c != null && c.moveToNext()) {
- return c.getString(1);
- } else {
- return "";
- }
- } catch (Exception e) {
- Log.e(TAG, "queryGenre exception", e);
- return null;
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
- private Long queryLong(int id, String column) {
- Cursor c = null;
- try {
- // for now we are only reading properties from the "objects" table
- c = mMediaProvider.query(mObjectsUri,
- new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
- if (c != null && c.moveToNext()) {
- return new Long(c.getLong(1));
- }
- } catch (Exception e) {
- } finally {
- if (c != null) {
- c.close();
- }
- }
- return null;
- }
-
- private String nameFromPath(String path) {
- // extract name from full path
- int start = 0;
- int lastSlash = path.lastIndexOf('/');
- if (lastSlash >= 0) {
- start = lastSlash + 1;
- }
- int end = path.length();
- if (end - start > 255) {
- end = start + 255;
- }
- return path.substring(start, end);
- }
-
- private MtpPropertyList getObjectPropertyList(int handle, int format, int property,
+ private MtpPropertyList getObjectPropertyList(long handle, int format, long property,
int groupCode, int depth) {
// FIXME - implement group support
- // For now we only support a single property at a time
if (groupCode != 0) {
return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED);
}
- if (depth > 1) {
- return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED);
- }
- String column = null;
- int type = MtpConstants.TYPE_UNDEFINED;
-
- switch (property) {
- case MtpConstants.PROPERTY_STORAGE_ID:
- // no query needed until we support multiple storage units
- // for now it is always mStorageID
- type = MtpConstants.TYPE_UINT32;
- break;
- case MtpConstants.PROPERTY_OBJECT_FORMAT:
- column = Files.FileColumns.FORMAT;
- type = MtpConstants.TYPE_UINT16;
- break;
- case MtpConstants.PROPERTY_PROTECTION_STATUS:
- // protection status is always 0
- type = MtpConstants.TYPE_UINT16;
- break;
- case MtpConstants.PROPERTY_OBJECT_SIZE:
- column = Files.FileColumns.SIZE;
- type = MtpConstants.TYPE_UINT64;
- break;
- case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
- column = Files.FileColumns.DATA;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_NAME:
- column = MediaColumns.TITLE;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_DATE_MODIFIED:
- column = Files.FileColumns.DATE_MODIFIED;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_DATE_ADDED:
- column = Files.FileColumns.DATE_ADDED;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
- column = Audio.AudioColumns.YEAR;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_PARENT_OBJECT:
- column = Files.FileColumns.PARENT;
- type = MtpConstants.TYPE_UINT32;
- break;
- case MtpConstants.PROPERTY_PERSISTENT_UID:
- // PUID is concatenation of storageID and object handle
- type = MtpConstants.TYPE_UINT128;
- break;
- case MtpConstants.PROPERTY_DURATION:
- column = Audio.AudioColumns.DURATION;
- type = MtpConstants.TYPE_UINT32;
- break;
- case MtpConstants.PROPERTY_TRACK:
- column = Audio.AudioColumns.TRACK;
- type = MtpConstants.TYPE_UINT16;
- break;
- case MtpConstants.PROPERTY_DISPLAY_NAME:
- column = MediaColumns.DISPLAY_NAME;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_ARTIST:
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_ALBUM_NAME:
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_ALBUM_ARTIST:
- column = Audio.AudioColumns.ALBUM_ARTIST;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_GENRE:
- // genre requires a special query
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_COMPOSER:
- column = Audio.AudioColumns.COMPOSER;
- type = MtpConstants.TYPE_STR;
- break;
- case MtpConstants.PROPERTY_DESCRIPTION:
- column = Images.ImageColumns.DESCRIPTION;
- type = MtpConstants.TYPE_STR;
- break;
- default:
- return new MtpPropertyList(0, MtpConstants.RESPONSE_OBJECT_PROP_NOT_SUPPORTED);
- }
-
- Cursor c = null;
- try {
- if (column != null) {
- c = mMediaProvider.query(mObjectsUri,
- new String [] { Files.FileColumns._ID, column },
- // depth 0: single record, depth 1: immediate children
- (depth == 0 ? ID_WHERE : PARENT_WHERE),
- new String[] { Integer.toString(handle) }, null);
- if (c == null) {
- return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
- }
- } else if (depth == 1) {
- c = mMediaProvider.query(mObjectsUri,
- new String [] { Files.FileColumns._ID },
- PARENT_WHERE, new String[] { Integer.toString(handle) }, null);
- if (c == null) {
- return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
- }
+ MtpPropertyGroup propertyGroup;
+ if (property == 0xFFFFFFFFL) {
+ propertyGroup = mPropertyGroupsByFormat.get(format);
+ if (propertyGroup == null) {
+ int[] propertyList = getSupportedObjectProperties(format);
+ propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mVolumeName, propertyList);
+ mPropertyGroupsByFormat.put(new Integer(format), propertyGroup);
}
-
- int count = (c == null ? 1 : c.getCount());
- MtpPropertyList result = new MtpPropertyList(count, MtpConstants.RESPONSE_OK);
-
- for (int index = 0; index < count; index++) {
- if (c != null) {
- c.moveToNext();
- }
- if (depth == 1) {
- handle = (int)c.getLong(0);
- }
-
- switch (property) {
- // handle special cases here
- case MtpConstants.PROPERTY_STORAGE_ID:
- result.setProperty(index, handle, property, MtpConstants.TYPE_UINT32,
- mStorageID);
- break;
- case MtpConstants.PROPERTY_PROTECTION_STATUS:
- // protection status is always 0
- result.setProperty(index, handle, property, MtpConstants.TYPE_UINT16, 0);
- break;
- case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
- // special case - need to extract file name from full path
- String value = c.getString(1);
- if (value != null) {
- result.setProperty(index, handle, property, nameFromPath(value));
- } else {
- result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
- }
- break;
- case MtpConstants.PROPERTY_NAME:
- // first try title
- String name = c.getString(1);
- // then try name
- if (name == null) {
- name = queryString(handle, Audio.PlaylistsColumns.NAME);
- }
- // if title and name fail, extract name from full path
- if (name == null) {
- name = queryString(handle, Files.FileColumns.DATA);
- if (name != null) {
- name = nameFromPath(name);
- }
- }
- if (name != null) {
- result.setProperty(index, handle, property, name);
- } else {
- result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
- }
- break;
- case MtpConstants.PROPERTY_DATE_MODIFIED:
- case MtpConstants.PROPERTY_DATE_ADDED:
- // convert from seconds to DateTime
- result.setProperty(index, handle, property, format_date_time(c.getInt(1)));
- break;
- case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
- // release date is stored internally as just the year
- int year = c.getInt(1);
- String dateTime = Integer.toString(year) + "0101T000000";
- result.setProperty(index, handle, property, dateTime);
- break;
- case MtpConstants.PROPERTY_PERSISTENT_UID:
- // PUID is concatenation of storageID and object handle
- long puid = mStorageID;
- puid <<= 32;
- puid += handle;
- result.setProperty(index, handle, property, MtpConstants.TYPE_UINT128, puid);
- break;
- case MtpConstants.PROPERTY_TRACK:
- result.setProperty(index, handle, property, MtpConstants.TYPE_UINT16,
- c.getInt(1) % 1000);
- break;
- case MtpConstants.PROPERTY_ARTIST:
- result.setProperty(index, handle, property, queryAudio(handle, Audio.AudioColumns.ARTIST));
- break;
- case MtpConstants.PROPERTY_ALBUM_NAME:
- result.setProperty(index, handle, property, queryAudio(handle, Audio.AudioColumns.ALBUM));
- break;
- case MtpConstants.PROPERTY_GENRE:
- String genre = queryGenre(handle);
- if (genre != null) {
- result.setProperty(index, handle, property, genre);
- } else {
- result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
- }
- break;
- default:
- if (type == MtpConstants.TYPE_STR) {
- result.setProperty(index, handle, property, c.getString(1));
- } else {
- result.setProperty(index, handle, property, type, c.getLong(1));
- }
- }
- }
-
- return result;
- } catch (RemoteException e) {
- return new MtpPropertyList(0, MtpConstants.RESPONSE_GENERAL_ERROR);
- } finally {
- if (c != null) {
- c.close();
+ } else {
+ propertyGroup = mPropertyGroupsByProperty.get(property);
+ if (propertyGroup == null) {
+ int[] propertyList = new int[] { (int)property };
+ propertyGroup = new MtpPropertyGroup(this, mMediaProvider, mVolumeName, propertyList);
+ mPropertyGroupsByProperty.put(new Integer((int)property), propertyGroup);
}
}
- // impossible to get here, so no return statement
+
+ return propertyGroup.getPropertyList((int)handle, format, depth, mStorageID);
}
private int renameFile(int handle, String newName) {
@@ -1028,5 +784,4 @@
private native final void native_setup();
private native final void native_finalize();
- private native String format_date_time(long seconds);
}
diff --git a/media/java/android/media/MtpPropertyGroup.java b/media/java/android/media/MtpPropertyGroup.java
new file mode 100644
index 0000000..bb733e2
--- /dev/null
+++ b/media/java/android/media/MtpPropertyGroup.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.content.IContentProvider;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Audio;
+import android.provider.MediaStore.Files;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.MediaColumns;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+class MtpPropertyGroup {
+
+ private static final String TAG = "MtpPropertyGroup";
+
+ private class Property {
+ // MTP property code
+ int code;
+ // MTP data type
+ int type;
+ // column index for our query
+ int column;
+
+ Property(int code, int type, int column) {
+ this.code = code;
+ this.type = type;
+ this.column = column;
+ }
+ }
+
+ private final MtpDatabase mDatabase;
+ private final IContentProvider mProvider;
+ private final String mVolumeName;
+ private final Uri mUri;
+
+ // list of all properties in this group
+ private final Property[] mProperties;
+
+ // list of columns for database query
+ private String[] mColumns;
+
+ private static final String ID_WHERE = Files.FileColumns._ID + "=?";
+ private static final String ID_FORMAT_WHERE = ID_WHERE + " AND "
+ + Files.FileColumns.FORMAT + "=?";
+ private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?";
+ private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND "
+ + Files.FileColumns.FORMAT + "=?";
+ // constructs a property group for a list of properties
+ public MtpPropertyGroup(MtpDatabase database, IContentProvider provider, String volume,
+ int[] properties) {
+ mDatabase = database;
+ mProvider = provider;
+ mVolumeName = volume;
+ mUri = Files.getMtpObjectsUri(volume);
+
+ int count = properties.length;
+ ArrayList<String> columns = new ArrayList<String>(count);
+ columns.add(Files.FileColumns._ID);
+
+ mProperties = new Property[count];
+ for (int i = 0; i < count; i++) {
+ mProperties[i] = createProperty(properties[i], columns);
+ }
+ count = columns.size();
+ mColumns = new String[count];
+ for (int i = 0; i < count; i++) {
+ mColumns[i] = columns.get(i);
+ }
+ }
+
+ private Property createProperty(int code, ArrayList<String> columns) {
+ String column = null;
+ int type;
+
+ switch (code) {
+ case MtpConstants.PROPERTY_STORAGE_ID:
+ // no query needed until we support multiple storage units
+ type = MtpConstants.TYPE_UINT32;
+ break;
+ case MtpConstants.PROPERTY_OBJECT_FORMAT:
+ column = Files.FileColumns.FORMAT;
+ type = MtpConstants.TYPE_UINT16;
+ break;
+ case MtpConstants.PROPERTY_PROTECTION_STATUS:
+ // protection status is always 0
+ type = MtpConstants.TYPE_UINT16;
+ break;
+ case MtpConstants.PROPERTY_OBJECT_SIZE:
+ column = Files.FileColumns.SIZE;
+ type = MtpConstants.TYPE_UINT64;
+ break;
+ case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
+ column = Files.FileColumns.DATA;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_NAME:
+ column = MediaColumns.TITLE;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_DATE_MODIFIED:
+ column = Files.FileColumns.DATE_MODIFIED;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_DATE_ADDED:
+ column = Files.FileColumns.DATE_ADDED;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
+ column = Audio.AudioColumns.YEAR;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_PARENT_OBJECT:
+ column = Files.FileColumns.PARENT;
+ type = MtpConstants.TYPE_UINT32;
+ break;
+ case MtpConstants.PROPERTY_PERSISTENT_UID:
+ // PUID is concatenation of storageID and object handle
+ type = MtpConstants.TYPE_UINT128;
+ break;
+ case MtpConstants.PROPERTY_DURATION:
+ column = Audio.AudioColumns.DURATION;
+ type = MtpConstants.TYPE_UINT32;
+ break;
+ case MtpConstants.PROPERTY_TRACK:
+ column = Audio.AudioColumns.TRACK;
+ type = MtpConstants.TYPE_UINT16;
+ break;
+ case MtpConstants.PROPERTY_DISPLAY_NAME:
+ column = MediaColumns.DISPLAY_NAME;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_ARTIST:
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_ALBUM_NAME:
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_ALBUM_ARTIST:
+ column = Audio.AudioColumns.ALBUM_ARTIST;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_GENRE:
+ // genre requires a special query
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_COMPOSER:
+ column = Audio.AudioColumns.COMPOSER;
+ type = MtpConstants.TYPE_STR;
+ break;
+ case MtpConstants.PROPERTY_DESCRIPTION:
+ column = Images.ImageColumns.DESCRIPTION;
+ type = MtpConstants.TYPE_STR;
+ break;
+ default:
+ type = MtpConstants.TYPE_UNDEFINED;
+ Log.e(TAG, "unsupported property " + code);
+ break;
+ }
+
+ if (column != null) {
+ columns.add(column);
+ return new Property(code, type, columns.size() - 1);
+ } else {
+ return new Property(code, type, -1);
+ }
+ }
+
+ private String queryString(int id, String column) {
+ Cursor c = null;
+ try {
+ // for now we are only reading properties from the "objects" table
+ c = mProvider.query(mUri,
+ new String [] { Files.FileColumns._ID, column },
+ ID_WHERE, new String[] { Integer.toString(id) }, null);
+ if (c != null && c.moveToNext()) {
+ return c.getString(1);
+ } else {
+ return "";
+ }
+ } catch (Exception e) {
+ return null;
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ private String queryAudio(int id, String column) {
+ Cursor c = null;
+ try {
+ c = mProvider.query(Audio.Media.getContentUri(mVolumeName),
+ new String [] { Files.FileColumns._ID, column },
+ ID_WHERE, new String[] { Integer.toString(id) }, null);
+ if (c != null && c.moveToNext()) {
+ return c.getString(1);
+ } else {
+ return "";
+ }
+ } catch (Exception e) {
+ return null;
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ private String queryGenre(int id) {
+ Cursor c = null;
+ try {
+ Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
+ c = mProvider.query(uri,
+ new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
+ null, null, null);
+ if (c != null && c.moveToNext()) {
+ return c.getString(1);
+ } else {
+ return "";
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "queryGenre exception", e);
+ return null;
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ private Long queryLong(int id, String column) {
+ Cursor c = null;
+ try {
+ // for now we are only reading properties from the "objects" table
+ c = mProvider.query(mUri,
+ new String [] { Files.FileColumns._ID, column },
+ ID_WHERE, new String[] { Integer.toString(id) }, null);
+ if (c != null && c.moveToNext()) {
+ return new Long(c.getLong(1));
+ }
+ } catch (Exception e) {
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ return null;
+ }
+
+ private static String nameFromPath(String path) {
+ // extract name from full path
+ int start = 0;
+ int lastSlash = path.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ start = lastSlash + 1;
+ }
+ int end = path.length();
+ if (end - start > 255) {
+ end = start + 255;
+ }
+ return path.substring(start, end);
+ }
+
+ MtpPropertyList getPropertyList(int handle, int format, int depth, int storageID) {
+ Log.d(TAG, "getPropertyList handle: " + handle + " format: " + format + " depth: " + depth);
+ if (depth > 1) {
+ // we only support depth 0 and 1
+ // depth 0: single object, depth 1: immediate children
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED);
+ }
+
+ String where;
+ String[] whereArgs;
+ if (format == 0) {
+ whereArgs = new String[] { Integer.toString(handle) };
+ if (depth == 1) {
+ where = PARENT_WHERE;
+ } else {
+ where = ID_WHERE;
+ }
+ } else {
+ whereArgs = new String[] { Integer.toString(handle), Integer.toString(format) };
+ if (depth == 1) {
+ where = PARENT_FORMAT_WHERE;
+ } else {
+ where = ID_FORMAT_WHERE;
+ }
+ }
+
+ Cursor c = null;
+ try {
+ // don't query if not necessary
+ if (depth > 0 || mColumns.length > 1) {
+ c = mProvider.query(mUri, mColumns, where, whereArgs, null);
+ if (c == null) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ }
+
+ int count = (c == null ? 1 : c.getCount());
+ MtpPropertyList result = new MtpPropertyList(count * mProperties.length,
+ MtpConstants.RESPONSE_OK);
+
+ // iterate over all objects in the query
+ for (int objectIndex = 0; objectIndex < count; objectIndex++) {
+ if (c != null) {
+ c.moveToNext();
+ }
+ if (depth == 1) {
+ handle = (int)c.getLong(0);
+ }
+
+ // iterate over all properties in the query for the given object
+ for (int propertyIndex = 0; propertyIndex < mProperties.length; propertyIndex++) {
+ Property property = mProperties[propertyIndex];
+ int propertyCode = property.code;
+ int column = property.column;
+
+ // handle some special cases
+ switch (propertyCode) {
+ case MtpConstants.PROPERTY_STORAGE_ID:
+ result.append(handle, propertyCode, MtpConstants.TYPE_UINT32,
+ storageID);
+ break;
+ case MtpConstants.PROPERTY_PROTECTION_STATUS:
+ // protection status is always 0
+ result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0);
+ break;
+ case MtpConstants.PROPERTY_OBJECT_FILE_NAME:
+ // special case - need to extract file name from full path
+ String value = c.getString(column);
+ if (value != null) {
+ result.append(handle, propertyCode, nameFromPath(value));
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ case MtpConstants.PROPERTY_NAME:
+ // first try title
+ String name = c.getString(column);
+ // then try name
+ if (name == null) {
+ name = queryString(handle, Audio.PlaylistsColumns.NAME);
+ }
+ // if title and name fail, extract name from full path
+ if (name == null) {
+ name = queryString(handle, Files.FileColumns.DATA);
+ if (name != null) {
+ name = nameFromPath(name);
+ }
+ }
+ if (name != null) {
+ result.append(handle, propertyCode, name);
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ case MtpConstants.PROPERTY_DATE_MODIFIED:
+ case MtpConstants.PROPERTY_DATE_ADDED:
+ // convert from seconds to DateTime
+ result.append(handle, propertyCode, format_date_time(c.getInt(column)));
+ break;
+ case MtpConstants.PROPERTY_ORIGINAL_RELEASE_DATE:
+ // release date is stored internally as just the year
+ int year = c.getInt(column);
+ String dateTime = Integer.toString(year) + "0101T000000";
+ result.append(handle, propertyCode, dateTime);
+ break;
+ case MtpConstants.PROPERTY_PERSISTENT_UID:
+ // PUID is concatenation of storageID and object handle
+ long puid = storageID;
+ puid <<= 32;
+ puid += handle;
+ result.append(handle, propertyCode, MtpConstants.TYPE_UINT128, puid);
+ break;
+ case MtpConstants.PROPERTY_TRACK:
+ result.append(handle, propertyCode, MtpConstants.TYPE_UINT16,
+ c.getInt(column) % 1000);
+ break;
+ case MtpConstants.PROPERTY_ARTIST:
+ result.append(handle, propertyCode,
+ queryAudio(handle, Audio.AudioColumns.ARTIST));
+ break;
+ case MtpConstants.PROPERTY_ALBUM_NAME:
+ result.append(handle, propertyCode,
+ queryAudio(handle, Audio.AudioColumns.ALBUM));
+ break;
+ case MtpConstants.PROPERTY_GENRE:
+ String genre = queryGenre(handle);
+ if (genre != null) {
+ result.append(handle, propertyCode, genre);
+ } else {
+ result.setResult(MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
+ }
+ break;
+ default:
+ if (property.type == MtpConstants.TYPE_STR) {
+ result.append(handle, propertyCode, c.getString(column));
+ } else if (property.type == MtpConstants.TYPE_UNDEFINED) {
+ result.append(handle, propertyCode, property.type, 0);
+ } else {
+ result.append(handle, propertyCode, property.type,
+ c.getLong(column));
+ }
+ break;
+ }
+ }
+ }
+
+ return result;
+ } catch (RemoteException e) {
+ return new MtpPropertyList(0, MtpConstants.RESPONSE_GENERAL_ERROR);
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ // impossible to get here, so no return statement
+ }
+
+ private native String format_date_time(long seconds);
+}
diff --git a/media/java/android/media/MtpPropertyList.java b/media/java/android/media/MtpPropertyList.java
index f598981..d3f0b34 100644
--- a/media/java/android/media/MtpPropertyList.java
+++ b/media/java/android/media/MtpPropertyList.java
@@ -19,14 +19,14 @@
/**
* Encapsulates the ObjectPropList dataset used by the GetObjectPropList command.
* The fields of this class are read by JNI code in android_media_MtpDatabase.cpp
- *
- * {@hide}
*/
-public class MtpPropertyList {
+class MtpPropertyList {
// number of results returned
- public final int mCount;
+ private int mCount;
+ // maximum number of results
+ private final int mMaxCount;
// result code for GetObjectPropList
public int mResult;
// list of object handles (first field in quadruplet)
@@ -41,18 +41,19 @@
public String[] mStringValues;
// constructor only called from MtpDatabase
- public MtpPropertyList(int count, int result) {
- mCount = count;
+ public MtpPropertyList(int maxCount, int result) {
+ mMaxCount = maxCount;
mResult = result;
- mObjectHandles = new int[count];
- mPropertyCodes = new int[count];
- mDataTypes = new int[count];
+ mObjectHandles = new int[maxCount];
+ mPropertyCodes = new int[maxCount];
+ mDataTypes = new int[maxCount];
// mLongValues and mStringValues are created lazily since both might not be necessary
}
- public void setProperty(int index, int handle, int property, int type, long value) {
+ public void append(int handle, int property, int type, long value) {
+ int index = mCount++;
if (mLongValues == null) {
- mLongValues = new long[mCount];
+ mLongValues = new long[mMaxCount];
}
mObjectHandles[index] = handle;
mPropertyCodes[index] = property;
@@ -60,9 +61,10 @@
mLongValues[index] = value;
}
- public void setProperty(int index, int handle, int property, String value) {
+ public void append(int handle, int property, String value) {
+ int index = mCount++;
if (mStringValues == null) {
- mStringValues = new String[mCount];
+ mStringValues = new String[mMaxCount];
}
mObjectHandles[index] = handle;
mPropertyCodes[index] = property;
diff --git a/media/jni/android_media_MtpDatabase.cpp b/media/jni/android_media_MtpDatabase.cpp
index f04a2ae..1909e6a 100644
--- a/media/jni/android_media_MtpDatabase.cpp
+++ b/media/jni/android_media_MtpDatabase.cpp
@@ -134,8 +134,7 @@
virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
- MtpObjectFormat format,
- MtpObjectProperty property,
+ uint32_t format, uint32_t property,
int groupCode, int depth,
MtpDataPacket& packet);
@@ -355,7 +354,7 @@
MtpDataPacket& packet) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
- (jint)handle, 0, (jint)property, 0, 0);
+ (jlong)handle, 0, (jlong)property, 0, 0);
MtpResponseCode result = env->GetIntField(list, field_mResult);
int count = env->GetIntField(list, field_mCount);
if (result == MTP_RESPONSE_OK && count != 1)
@@ -646,18 +645,19 @@
}
MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
- MtpObjectFormat format,
- MtpObjectProperty property,
+ uint32_t format, uint32_t property,
int groupCode, int depth,
MtpDataPacket& packet) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
- (jint)handle, (jint)format, (jint)property, (jint)groupCode, (jint)depth);
+ (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ if (!list)
+ return MTP_RESPONSE_GENERAL_ERROR;
int count = env->GetIntField(list, field_mCount);
MtpResponseCode result = env->GetIntField(list, field_mResult);
packet.putUInt32(count);
-
if (count > 0) {
jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
@@ -1042,7 +1042,7 @@
}
static jstring
-android_media_MtpDatabase_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
+android_media_MtpPropertyGroup_format_date_time(JNIEnv *env, jobject thiz, jlong seconds)
{
#ifdef HAVE_ANDROID_OS
char date[20];
@@ -1055,11 +1055,14 @@
// ----------------------------------------------------------------------------
-static JNINativeMethod gMethods[] = {
+static JNINativeMethod gMtpDatabaseMethods[] = {
{"native_setup", "()V", (void *)android_media_MtpDatabase_setup},
{"native_finalize", "()V", (void *)android_media_MtpDatabase_finalize},
+};
+
+static JNINativeMethod gMtpPropertyGroupMethods[] = {
{"format_date_time", "(J)Ljava/lang/String;",
- (void *)android_media_MtpDatabase_format_date_time},
+ (void *)android_media_MtpPropertyGroup_format_date_time},
};
static const char* const kClassPathName = "android/media/MtpDatabase";
@@ -1131,7 +1134,7 @@
return -1;
}
method_getObjectPropertyList = env->GetMethodID(clazz, "getObjectPropertyList",
- "(IIIII)Landroid/media/MtpPropertyList;");
+ "(JIJII)Landroid/media/MtpPropertyList;");
if (method_getObjectPropertyList == NULL) {
LOGE("Can't find getObjectPropertyList");
return -1;
@@ -1220,6 +1223,10 @@
return -1;
}
+ if (AndroidRuntime::registerNativeMethods(env,
+ "android/media/MtpDatabase", gMtpDatabaseMethods, NELEM(gMtpDatabaseMethods)))
+ return -1;
+
return AndroidRuntime::registerNativeMethods(env,
- "android/media/MtpDatabase", gMethods, NELEM(gMethods));
+ "android/media/MtpPropertyGroup", gMtpPropertyGroupMethods, NELEM(gMtpPropertyGroupMethods));
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index ec3b5a2..d2dbf0d 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -366,6 +366,9 @@
return BAD_VALUE;
}
+ if (timeUs <= 15 * 1000000LL) {
+ LOGW("Target duration (%lld us) too short to be respected", timeUs);
+ }
mMaxFileDurationUs = timeUs;
return OK;
}
@@ -376,6 +379,11 @@
LOGE("Max file size is too small: %lld bytes", bytes);
return BAD_VALUE;
}
+
+ if (bytes <= 100 * 1024) {
+ LOGW("Target file size (%lld bytes) is too small to be respected", bytes);
+ }
+
mMaxFileSizeBytes = bytes;
return OK;
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6760707..602aa9f 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -878,7 +878,10 @@
nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
}
- return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes);
+ // Be conservative in the estimate: do not exceed 95% of
+ // the target file limit. For small target file size limit, though,
+ // this will not help.
+ return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100);
}
bool MPEG4Writer::exceedsFileDurationLimit() {
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index 900b517..9929805 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -77,8 +77,7 @@
virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property) = 0;
virtual MtpResponseCode getObjectPropertyList(MtpObjectHandle handle,
- MtpObjectFormat format,
- MtpObjectProperty property,
+ uint32_t format, uint32_t property,
int groupCode, int depth,
MtpDataPacket& packet) = 0;
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 42945f5..4356a6f 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -53,7 +53,7 @@
mDefaultArrayValues(NULL),
mCurrentArrayLength(0),
mCurrentArrayValues(NULL),
- mGroupCode(-1), // disable multiple properties in GetObjectPropList for now
+ mGroupCode(0),
mFormFlag(kFormNone),
mEnumLength(0),
mEnumValues(NULL)
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index c3755f3..de6cbac 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -536,8 +536,9 @@
MtpResponseCode MtpServer::doGetObjectPropList() {
MtpObjectHandle handle = mRequest.getParameter(1);
- MtpObjectFormat format = mRequest.getParameter(2);
- MtpDeviceProperty property = mRequest.getParameter(3);
+ // use uint32_t so we can support 0xFFFFFFFF
+ uint32_t format = mRequest.getParameter(2);
+ uint32_t property = mRequest.getParameter(3);
int groupCode = mRequest.getParameter(4);
int depth = mRequest.getParameter(5);
LOGD("GetObjectPropList %d format: %s property: %s group: %d depth: %d\n",
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index 078daa7..b0597c4e 100755
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.defcontainer">
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
+ <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS"/>
<uses-permission android:name="android.permission.ASEC_ACCESS"/>
<uses-permission android:name="android.permission.ASEC_CREATE"/>
<uses-permission android:name="android.permission.ASEC_DESTROY"/>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index cfdf0dd..21c0645 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"UI systému"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazat"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nerušit"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Zobrazit upozornění"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žádná oznámení"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Probíhající"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Oznámení"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Prosím připojte dobíjecí zařízení"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterie je vybitá:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Baterie je vybitá."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Zbývá <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Nabíjení pomocí rozhraní USB není podporováno."\n"Používejte pouze nabíječku, která byla dodána se zařízením."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Využití baterie"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Žádné nedávno použité aplikace."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Obrazovka se automaticky otočí."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Otáčení obrazovky je uzamčeno."</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index e4fc728..a569aa4 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"System-UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Forstyr ikke"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis meddelelser"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelelser"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Forbind oplader"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Opladning via USB understøttes ikke."\n"Brug kun den medfølgende oplader."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Batteriforbrug"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Der er ingen nye programmer."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Skærmen roterer automatisk."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Skærmrotationen er nu låst."</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index edb1bef..fce8200 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"System-UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Bitte nicht stören"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Benachrichtigungen zeigen"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Keine Benachrichtigungen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktuell"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Ladegerät anschließen"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Akku ist fast leer."</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Akku ist fast leer."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Noch <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB-Aufladung wird nicht unterstützt."\n"Verwenden Sie das mitgelieferte Aufladegerät."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Akkuverbrauch"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Zuletzt verwendet"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Keine neuen Anwendungen"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Bildschirm wird automatisch gedreht."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Bildschirmrotation ist jetzt gesperrt."</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 21ea803..01bf5a1 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"UI συστήματ."</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Εκκαθάριση"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Μην ενοχλείτε"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Εμφάνιση ειδοποιήσεων"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Εν εξελίξει"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Ειδοποιήσεις"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Συνδέστε τον φορτιστή"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Η στάθμη της μπαταρίας είναι χαμηλή:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Η στάθμη της μπαταρίας είναι χαμηλή."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Απομένει <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Δεν υποστηρίζεται η φόρτιση USB."\n"Χρησιμοποιείτε μόνο τον φορτιστή που παρέχεται."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Χρήση μπαταρίας"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Δεν υπάρχουν πρόσφατες εφαρμογές."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Η περιστροφή οθόνης είναι κλειδωμένη."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b6d3618..e2172c0 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Sistema UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Hay poca batería:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Hay poca batería."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Quedan <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"No admite la carga USB."\n"Usa sólo el cargador provisto."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"La pantalla rotará automáticamente."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"La rotación de la pantalla se encuentra actualmente bloqueada."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 77773af..b402e15 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"IU sistema"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificaciones"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Conecta el cargador"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Se está agotando la batería:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Se está agotando la batería."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"No se admite la carga por USB."\n"Utiliza solo el cargador proporcionado."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Uso de la batería"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"No hay aplicaciones recientes."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"La pantalla girará automáticamente."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"La rotación de la pantalla esta bloqueada."</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 8877329..70d2a51 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"IU système"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Effacer"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ne pas déranger"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Afficher les notifications"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Branchez le chargeur"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Le niveau de la batterie est bas :"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Le niveau de la batterie est faible."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restant(s)"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Chargement USB non disponible."\n"Vous devez utiliser le chargeur fourni."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Utilisation de la batterie"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Aucune application récente"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"L\'écran pivote automatiquement."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"La rotation de l\'écran est verrouillée."</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 0507cf9..4b16033 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"UI sistema"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Cancella"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Non disturbare"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostra notifiche"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nessuna notifica"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"In corso"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifiche"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Collegare il caricabatterie"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteria quasi scarica:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteria quasi scarica."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> rimanente"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Ricarica tramite USB non supportata."\n"Utilizza solo il caricatore in dotazione."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Utilizzo batteria"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Nessuna applicazione recente."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Lo schermo ruoterà automaticamente."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"La rotazione dello schermo è bloccata."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 782d03b..b2b6c54 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"システムUI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"通知を消去"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"通知を非表示"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"通知を表示"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"通知なし"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"実行中"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
<string name="battery_low_title" msgid="7923774589611311406">"充電してください"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"電池が残り少なくなっています:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"電池が残り少なくなっています。"</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"残り<xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB充電には対応していません。"\n"付属の充電器をお使いください。"</string>
<string name="battery_low_why" msgid="7279169609518386372">"電池使用量"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"新着のアプリケーションはありません。"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"画面は自動的に回転します。"</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"画面の回転をロックしました。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5e9b9d5..d550253 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"시스템 UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"지우기"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"응답 거부"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"알림 표시"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"알림 없음"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"진행 중"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"알림"</string>
<string name="battery_low_title" msgid="7923774589611311406">"충전기를 연결하세요."</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"배터리 전원이 부족합니다."</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"배터리 전원이 부족합니다."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g>개 남음"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB 충전이 지원되지 않습니다."\n"제공된 충전기만 사용하세요."</string>
<string name="battery_low_why" msgid="7279169609518386372">"배터리 사용량"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"최근에 사용한 애플리케이션이 없습니다."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"화면은 자동으로 회전합니다."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"현재 화면 회전이 잠겨 있습니다."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 147242f..1eb7851e 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Sys.gr.snitt"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Fjern"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Ikke forstyrr"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Vis varslinger"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen varslinger"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktiviteter"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Varslinger"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Koble til en lader"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er nesten tomt:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Lavt batterinivå."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> gjenværende"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB-lading støttes ikke."\n"Bruk kun den medfølgende laderen."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Batteribruk"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Ingen nylig brukte programmer."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Skjermen vil rotere automatisk."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Skjermrotering er låst."</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 6067cca..c642240 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Systeem-UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Niet storen"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Meldingen weergeven"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meldingen"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Sluit de oplader aan"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"De accu raakt op:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"De accu raakt leeg."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> resterend"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Opladen via USB niet ondersteund."\n"Gebruik alleen de bijgeleverde oplader."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Accugebruik"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Geen recente toepassingen."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Scherm wordt automatisch geroteerd."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Schermrotatie is nu vergrendeld."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 6b19a34..4f5f328 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Interfejs"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wyczyść"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Nie przeszkadzać"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Pokaż powiadomienia"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Brak powiadomień"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Bieżące"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Powiadomienia"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Podłącz ładowarkę"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria się rozładowuje:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Bateria wkrótce zostanie rozładowana."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Pozostało: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Ładowanie przy użyciu złącza USB nie jest obsługiwane."\n"Należy używać tylko dołączonej ładowarki."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Użycie baterii"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Brak ostatnio używanych aplikacji."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Ekran zostanie obrócony automatycznie."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Obracanie ekranu zostało zablokowane."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 7bf6eb4..8ec603a 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"IU do sist."</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Não incomodar"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificações"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em curso"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Ligue o carregador"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está a ficar fraca:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está a ficar fraca."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Carregamento USB não suportado. "\n"Utilize apenas o carregador fornecido."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Utilização da bateria"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhuma aplicação recente."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"O ecrã será rodado automaticamente."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"A rotação do ecrã está agora bloqueada."</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 14b4b1f..6f98ed6 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Interf sist"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Não perturbe"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificações"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificações"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Conecte o carregador"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está ficando baixa:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"A bateria está ficando baixa."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> restante"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"O carregamento via USB não é suportado."\n"Use apenas o carregador fornecido."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Uso da bateria"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Nenhum aplicativo recente."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"A tela girará automaticamente."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"A rotação da tela está bloqueada."</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0a15bcd..471525f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Графический интерфейс системы"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Очистить"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Не беспокоить"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Показать уведомления"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Нет уведомлений"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Текущие"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Уведомления"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Подключите зарядное устройство"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Новых приложений нет"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Экран будет поворачиваться автоматически."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Поворот экрана заблокирован."</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 06188ab..7b7f29f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Gränssnitt"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Stör ej"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Visa aviseringar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Inga aviseringar"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Pågående"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelanden"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Anslut laddaren"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet håller på att ta slut:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet håller på att ta slut."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> återstår"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"Det går inte att ladda via USB."\n"Använd endast den laddare som levererades med telefonen."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Batteriförbrukning"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Inga nya program."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Skärmen roteras automatiskt."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Skärmrotationen är nu låst."</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 253fbe0..7c31960 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"Sist Arayüzü"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Temizle"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Rahatsız etmeyin"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Bildirimleri göster"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirim yok"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sürüyor"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Bildirimler"</string>
<string name="battery_low_title" msgid="7923774589611311406">"Lütfen şarj cihazını takın"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"Pil tükeniyor:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"Pil azalıyor."</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> kaldı"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"USB üzerinden şarj desteklenmiyor."\n"Yalnızca ürünle birlikte verilen şarj cihazını kullanın."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Pil kullanımı"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"Hiçbir yeni uygulama yok."</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"Ekran otomatik olarak dönecektir."</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"Ekran dönüşü şimdi kilitlendi."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 161a085..4705013 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"系统用户界面"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"请勿打扰"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"显示通知"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"无通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"正在进行的"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
<string name="battery_low_title" msgid="7923774589611311406">"请连接充电器"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"电量所剩不多:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"电池电量低。"</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"还剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"不支持 USB 充电功能。"\n"只能使用随附的充电器充电。"</string>
<string name="battery_low_why" msgid="7279169609518386372">"电量使用情况"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"没有最近使用的应用程序。"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"屏幕会自动旋转。"</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"屏幕旋转现已锁定。"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index eb9108d..ec9c298 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -19,22 +19,17 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (7164937344850004466) -->
- <skip />
+ <string name="app_label" msgid="7164937344850004466">"系統 UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
- <!-- no translation found for status_bar_do_not_disturb_button (5812628897510997853) -->
- <skip />
- <!-- no translation found for status_bar_please_disturb_button (3345398298841572813) -->
- <skip />
+ <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"勿干擾"</string>
+ <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"顯示通知"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"沒有通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"進行中"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string>
<string name="battery_low_title" msgid="7923774589611311406">"請連接充電器"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"電池電量即將不足:"</string>
- <!-- no translation found for battery_low_percent_format (1077244949318261761) -->
- <skip />
- <!-- no translation found for invalid_charger (4549105996740522523) -->
- <skip />
+ <string name="battery_low_subtitle" msgid="1752040062087829196">"電池電量即將不足。"</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"還剩 <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="invalid_charger" msgid="4549105996740522523">"不支援 USB 充電。"\n"僅能使用隨附的充電器。"</string>
<string name="battery_low_why" msgid="7279169609518386372">"電池使用狀況"</string>
<!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
<skip />
@@ -45,12 +40,9 @@
<!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
- <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
- <skip />
+ <string name="recent_tasks_empty" msgid="1905484479067697884">"沒有最近用過的應用程式。"</string>
<!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
<skip />
- <!-- no translation found for toast_rotation_free (2700542202836832631) -->
- <skip />
- <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
- <skip />
+ <string name="toast_rotation_free" msgid="2700542202836832631">"螢幕會自動旋轉。"</string>
+ <string name="toast_rotation_locked" msgid="7484691306949652450">"螢幕旋轉功能現已鎖定。"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index d1e61a9..4d0835f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -169,7 +169,7 @@
thumb = new DragThumbnailBuilder(mWindow.findViewById(R.id.preview));
}
- v.startDrag(clip, thumb, false);
+ v.startDrag(clip, thumb, false, null);
// TODO: only discard the clipping if it was accepted
stash(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 3519e8c..563b8ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -654,6 +654,12 @@
// called by StatusBar
@Override
public void setLightsOn(boolean on) {
+ // Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
+ // that can't handle lights-out mode.
+ if (mMenuButton.getVisibility() == View.VISIBLE
+ || mMenuShadow.getVisibility() == View.VISIBLE) {
+ on = true;
+ }
mHandler.removeMessages(MSG_SHOW_SHADOWS);
mHandler.removeMessages(MSG_HIDE_SHADOWS);
mHandler.sendEmptyMessage(on ? MSG_HIDE_SHADOWS : MSG_SHOW_SHADOWS);
@@ -664,6 +670,9 @@
Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
}
mMenuButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+
+ // See above re: lights-out policy for legacy apps.
+ if (visible) setLightsOn(true);
}
public void setIMEButtonVisible(IBinder token, boolean visible) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index cd8a065..138dff7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -160,6 +160,8 @@
private ContextMenuBuilder mContextMenu;
private MenuDialogHelper mContextMenuHelper;
+ private ActionButtonSubmenu mActionButtonPopup;
+ private boolean mClosingActionMenu;
private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
@@ -542,6 +544,9 @@
if (doCallback) {
callOnPanelClosed(st.featureId, st, null);
}
+ } else if (st.featureId == FEATURE_OPTIONS_PANEL && doCallback &&
+ mActionBar != null) {
+ checkCloseActionMenu(st.menu);
}
st.isPrepared = false;
st.isHandled = false;
@@ -563,6 +568,27 @@
}
}
+ private void checkCloseActionMenu(Menu menu) {
+ if (mClosingActionMenu) {
+ return;
+ }
+
+ boolean closed = false;
+ mClosingActionMenu = true;
+ if (mActionBar.isOverflowMenuOpen() && mActionBar.hideOverflowMenu()) {
+ closed = true;
+ }
+ if (mActionButtonPopup != null) {
+ mActionButtonPopup.dismiss();
+ closed = true;
+ }
+ Callback cb = getCallback();
+ if (cb != null && closed) {
+ cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
+ }
+ mClosingActionMenu = false;
+ }
+
@Override
public final void togglePanel(int featureId, KeyEvent event) {
PanelFeatureState st = getPanelState(featureId, true);
@@ -842,7 +868,12 @@
// The window manager will give us a valid window token
new MenuDialogHelper(subMenu).show(null);
} else {
- new MenuPopupHelper(getContext(), subMenu).show();
+ mActionButtonPopup = new ActionButtonSubmenu(getContext(), subMenu);
+ mActionButtonPopup.show();
+ Callback cb = getCallback();
+ if (cb != null) {
+ cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
+ }
}
return true;
@@ -854,16 +885,21 @@
private void reopenMenu(boolean toggleMenuMode) {
if (mActionBar != null) {
+ final Callback cb = getCallback();
if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
- final Callback cb = getCallback();
if (cb != null) {
final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
if (cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
- mActionBar.showOverflowMenu();
+ cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
+ mActionBar.openOverflowMenu();
}
}
} else {
mActionBar.hideOverflowMenu();
+ if (cb != null) {
+ final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
+ cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
+ }
}
return;
}
@@ -2042,8 +2078,23 @@
if (cb != null && mFeatureId < 0) {
cb.onDetachedFromWindow();
}
+
+ if (mActionButtonPopup != null) {
+ if (mActionButtonPopup.isShowing()) {
+ mActionButtonPopup.dismiss();
+ }
+ mActionButtonPopup = null;
+ }
}
-
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ if (mActionButtonPopup != null) {
+ mActionButtonPopup.dismiss();
+ post(mActionButtonPopup);
+ }
+ }
+
@Override
public void onCloseSystemDialogs(String reason) {
if (mFeatureId >= 0) {
@@ -2921,4 +2972,29 @@
void sendCloseSystemWindows(String reason) {
PhoneWindowManager.sendCloseSystemWindows(getContext(), reason);
}
+
+ private class ActionButtonSubmenu extends MenuPopupHelper implements Runnable {
+ private SubMenuBuilder mSubMenu;
+
+ public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
+ super(context, subMenu);
+ mSubMenu = subMenu;
+ }
+
+ @Override
+ public void onDismiss() {
+ super.onDismiss();
+ mSubMenu.getCallback().onCloseSubMenu(mSubMenu);
+ mActionButtonPopup = null;
+ }
+
+ @Override
+ public void run() {
+ show();
+ Callback cb = getCallback();
+ if (cb != null) {
+ cb.onMenuOpened(FEATURE_ACTION_BAR, mSubMenu);
+ }
+ }
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c528745..c3112d8 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1820,12 +1820,12 @@
final IStatusBarService sbs = mStatusBarService;
if (mStatusBarService != null) {
try {
- if (changedFullscreen) {
- sbs.setActiveWindowIsFullscreen(topIsFullscreenF);
- }
if (changedMenu) {
sbs.setMenuKeyVisible(topNeedsMenuF);
}
+ if (changedFullscreen) {
+ sbs.setActiveWindowIsFullscreen(topIsFullscreenF);
+ }
} catch (RemoteException e) {
// This should be impossible because we're in the same process.
mStatusBarService = null;
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index e3b5db1..175f613 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -81,12 +81,6 @@
LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address);
// keep track of SCO device address
mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
-#ifdef WITH_A2DP
- if (mA2dpOutput != 0 &&
- mPhoneState != AudioSystem::MODE_NORMAL) {
- mpClientInterface->suspendOutput(mA2dpOutput);
- }
-#endif
}
}
break;
@@ -115,12 +109,6 @@
{
if (AudioSystem::isBluetoothScoDevice(device)) {
mScoDeviceAddress = "";
-#ifdef WITH_A2DP
- if (mA2dpOutput != 0 &&
- mPhoneState != AudioSystem::MODE_NORMAL) {
- mpClientInterface->restoreOutput(mA2dpOutput);
- }
-#endif
}
}
} break;
@@ -138,6 +126,7 @@
if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
closeA2dpOutputs();
}
+ checkA2dpSuspend();
#endif
updateDeviceForStrategy();
setOutputDevice(mHardwareOutput, newDevice);
@@ -280,14 +269,7 @@
newDevice = getNewDevice(mHardwareOutput, false);
#ifdef WITH_A2DP
checkOutputForAllStrategies();
- // suspend A2DP output if a SCO device is present.
- if (mA2dpOutput != 0 && mScoDeviceAddress != "") {
- if (oldState == AudioSystem::MODE_NORMAL) {
- mpClientInterface->suspendOutput(mA2dpOutput);
- } else if (state == AudioSystem::MODE_NORMAL) {
- mpClientInterface->restoreOutput(mA2dpOutput);
- }
- }
+ checkA2dpSuspend();
#endif
updateDeviceForStrategy();
@@ -397,6 +379,7 @@
uint32_t newDevice = getNewDevice(mHardwareOutput, false);
#ifdef WITH_A2DP
checkOutputForAllStrategies();
+ checkA2dpSuspend();
#endif
updateDeviceForStrategy();
setOutputDevice(mHardwareOutput, newDevice);
@@ -1025,8 +1008,10 @@
#ifdef AUDIO_POLICY_TEST
Thread(false),
#endif //AUDIO_POLICY_TEST
- mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false),
- mLastVoiceVolume(-1.0f), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0)
+ mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0),
+ mMusicStopTime(0), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
+ mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
+ mA2dpSuspended(false)
{
mpClientInterface = clientInterface;
@@ -1322,17 +1307,6 @@
}
AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
- if (mScoDeviceAddress != "") {
- // It is normal to suspend twice if we are both in call,
- // and have the hardware audio output routed to BT SCO
- if (mPhoneState != AudioSystem::MODE_NORMAL) {
- mpClientInterface->suspendOutput(mA2dpOutput);
- }
- if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
- mpClientInterface->suspendOutput(mA2dpOutput);
- }
- }
-
if (!a2dpUsedForSonification()) {
// mute music on A2DP output if a notification or ringtone is playing
uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION);
@@ -1340,6 +1314,9 @@
setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
}
}
+
+ mA2dpSuspended = false;
+
return NO_ERROR;
}
@@ -1369,6 +1346,7 @@
}
}
mA2dpDeviceAddress = "";
+ mA2dpSuspended = false;
return NO_ERROR;
}
@@ -1467,6 +1445,48 @@
checkOutputForStrategy(STRATEGY_DTMF);
}
+void AudioPolicyManagerBase::checkA2dpSuspend()
+{
+ // suspend A2DP output if:
+ // (NOT already suspended) &&
+ // ((SCO device is connected &&
+ // (forced usage for communication || for record is SCO))) ||
+ // (phone state is ringing || in call)
+ //
+ // restore A2DP output if:
+ // (Already suspended) &&
+ // ((SCO device is NOT connected ||
+ // (forced usage NOT for communication && NOT for record is SCO))) &&
+ // (phone state is NOT ringing && NOT in call)
+ //
+ if (mA2dpOutput == 0) {
+ return;
+ }
+
+ if (mA2dpSuspended) {
+ if (((mScoDeviceAddress == "") ||
+ ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) &&
+ (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) &&
+ ((mPhoneState != AudioSystem::MODE_IN_CALL) &&
+ (mPhoneState != AudioSystem::MODE_RINGTONE))) {
+
+ mpClientInterface->restoreOutput(mA2dpOutput);
+ mA2dpSuspended = false;
+ }
+ } else {
+ if (((mScoDeviceAddress != "") &&
+ ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
+ (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) ||
+ ((mPhoneState == AudioSystem::MODE_IN_CALL) ||
+ (mPhoneState == AudioSystem::MODE_RINGTONE))) {
+
+ mpClientInterface->suspendOutput(mA2dpOutput);
+ mA2dpSuspended = true;
+ }
+ }
+}
+
+
#endif
uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache)
@@ -1714,14 +1734,7 @@
// wait for the PCM output buffers to empty before proceeding with the rest of the command
usleep(outputDesc->mLatency*2*1000);
}
-#ifdef WITH_A2DP
- // suspend A2DP output if SCO device is selected
- if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
- if (mA2dpOutput != 0) {
- mpClientInterface->suspendOutput(mA2dpOutput);
- }
- }
-#endif
+
// do the routing
AudioParameter param = AudioParameter();
param.addInt(String8(AudioParameter::keyRouting), (int)device);
@@ -1729,15 +1742,6 @@
// update stream volumes according to new device
applyStreamVolumes(output, device, delayMs);
-#ifdef WITH_A2DP
- // if disconnecting SCO device, restore A2DP output
- if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)prevDevice)) {
- if (mA2dpOutput != 0) {
- LOGV("restore A2DP output");
- mpClientInterface->restoreOutput(mA2dpOutput);
- }
- }
-#endif
// if changing from a combined headset + speaker route, unmute media streams
if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {
setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index d523fa8..7f81a25 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -197,7 +197,7 @@
WifiServiceHandler(android.os.Looper looper, Context context) {
super(looper);
mWshChannel = new AsyncChannel();
- mWshChannel.connect(context, this, mWifiStateMachine.getHandler(), 0);
+ mWshChannel.connect(context, this, mWifiStateMachine.getHandler());
}
@Override
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 27ec1af..d7a6a0e 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -619,7 +619,7 @@
if (mDragInProgress && newWin.isPotentialDragTarget()) {
DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
- desc, null, false);
+ null, desc, null, false);
try {
newWin.mClient.dispatchDragEvent(event);
// track each window that we've notified that the drag is starting
@@ -659,7 +659,7 @@
Slog.d(TAG, "broadcasting DRAG_ENDED");
}
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
- 0, 0, null, null, mDragResult);
+ 0, 0, null, null, null, mDragResult);
for (WindowState ws: mNotifiedWindows) {
try {
ws.mClient.dispatchDragEvent(evt);
@@ -711,7 +711,7 @@
// force DRAG_EXITED_EVENT if appropriate
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
- null, null, false);
+ null, null, null, false);
mTargetWindow.mClient.dispatchDragEvent(evt);
if (myPid != mTargetWindow.mSession.mPid) {
evt.recycle();
@@ -723,7 +723,7 @@
}
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, null, false);
+ null, null, null, false);
touchedWin.mClient.dispatchDragEvent(evt);
if (myPid != touchedWin.mSession.mPid) {
evt.recycle();
@@ -754,7 +754,7 @@
final IBinder token = touchedWin.mClient.asBinder();
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, mData, false);
+ null, null, mData, false);
try {
touchedWin.mClient.dispatchDragEvent(evt);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 2de1cbb..ca87b4e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -23,6 +23,7 @@
import com.android.layoutlib.api.LayoutBridge;
import com.android.layoutlib.api.SceneParams;
import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.SceneResult.SceneStatus;
import com.android.layoutlib.bridge.android.BridgeAssetManager;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
@@ -308,8 +309,13 @@
return new BridgeLayoutScene(scene, lastResult);
} catch (Throwable t) {
- t.printStackTrace();
- return new BridgeLayoutScene(null, new SceneResult("error!", t));
+ // get the real cause of the exception.
+ Throwable t2 = t;
+ while (t2.getCause() != null) {
+ t2 = t.getCause();
+ }
+ return new BridgeLayoutScene(null,
+ new SceneResult(SceneStatus.ERROR_UNKNOWN, t2.getMessage(), t2));
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
index 97bf857..f807214 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -16,12 +16,16 @@
package com.android.layoutlib.bridge;
+import com.android.layoutlib.api.IXmlPullParser;
import com.android.layoutlib.api.LayoutScene;
import com.android.layoutlib.api.SceneParams;
import com.android.layoutlib.api.SceneResult;
import com.android.layoutlib.api.ViewInfo;
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
+import android.view.View;
+import android.view.ViewGroup;
+
import java.awt.image.BufferedImage;
import java.util.Map;
@@ -92,13 +96,86 @@
}
@Override
- public void dispose() {
- // TODO Auto-generated method stub
+ public SceneResult insertChild(Object parentView, IXmlPullParser childXml, Object beforeSibling,
+ IAnimationListener listener) {
+ if (parentView instanceof ViewGroup == false) {
+ throw new IllegalArgumentException("parentView is not a ViewGroup");
+ }
+ if (beforeSibling != null && beforeSibling instanceof View == false) {
+ throw new IllegalArgumentException("beforeSibling is not a View");
+ }
+ try {
+ mScene.prepareThread();
+ mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
+ if (mLastResult == SceneResult.SUCCESS) {
+ mLastResult = mScene.insertChild((ViewGroup) parentView, childXml,
+ (View) beforeSibling, listener);
+ }
+ } finally {
+ mScene.release();
+ mScene.cleanupThread();
+ }
+
+ return mLastResult;
+ }
+
+
+ @Override
+ public SceneResult moveChild(Object parentView, Object childView, Object beforeSibling,
+ IAnimationListener listener) {
+ if (parentView instanceof ViewGroup == false) {
+ throw new IllegalArgumentException("parentView is not a ViewGroup");
+ }
+ if (childView instanceof View == false) {
+ throw new IllegalArgumentException("childView is not a View");
+ }
+ if (beforeSibling != null && beforeSibling instanceof View == false) {
+ throw new IllegalArgumentException("beforeSibling is not a View");
+ }
+
+ try {
+ mScene.prepareThread();
+ mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
+ if (mLastResult == SceneResult.SUCCESS) {
+ mLastResult = mScene.moveChild((ViewGroup) parentView, (View) childView,
+ (View) beforeSibling, listener);
+ }
+ } finally {
+ mScene.release();
+ mScene.cleanupThread();
+ }
+
+ return mLastResult;
+ }
+
+ @Override
+ public SceneResult removeChild(Object childView, IAnimationListener listener) {
+ if (childView instanceof View == false) {
+ throw new IllegalArgumentException("childView is not a View");
+ }
+
+ try {
+ mScene.prepareThread();
+ mLastResult = mScene.acquire(SceneParams.DEFAULT_TIMEOUT);
+ if (mLastResult == SceneResult.SUCCESS) {
+ mLastResult = mScene.removeChild((View) childView, listener);
+ }
+ } finally {
+ mScene.release();
+ mScene.cleanupThread();
+ }
+
+ return mLastResult;
+ }
+
+ @Override
+ public void dispose() {
}
/*package*/ BridgeLayoutScene(LayoutSceneImpl scene, SceneResult lastResult) {
mScene = scene;
+ mScene.setScene(this);
mLastResult = lastResult;
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
index c20bdfd..d5766ab 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/AnimationThread.java
@@ -105,7 +105,7 @@
try {
bundle.mTarget.handleMessage(bundle.mMessage);
if (mScene.render() == SceneResult.SUCCESS) {
- mListener.onNewFrame(mScene.getImage());
+ mListener.onNewFrame(mScene.getScene());
}
} finally {
mScene.release();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index 8a07767..05d207c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -24,13 +24,16 @@
import com.android.layoutlib.api.IProjectCallback;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.api.IXmlPullParser;
import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.LayoutScene;
import com.android.layoutlib.api.SceneParams;
import com.android.layoutlib.api.SceneResult;
import com.android.layoutlib.api.ViewInfo;
import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
import com.android.layoutlib.api.LayoutScene.IAnimationListener;
import com.android.layoutlib.api.SceneParams.RenderingMode;
+import com.android.layoutlib.api.SceneResult.SceneStatus;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
@@ -53,6 +56,7 @@
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.widget.FrameLayout;
@@ -92,6 +96,7 @@
private final SceneParams mParams;
// scene state
+ private LayoutScene mScene;
private BridgeContext mContext;
private BridgeXmlBlockParser mBlockParser;
private BridgeInflater mInflater;
@@ -362,7 +367,7 @@
return SceneResult.SUCCESS;
} catch (PostInflateException e) {
- return new SceneResult("Error during post inflation process:\n" + e.getMessage());
+ return new SceneResult(SceneStatus.ERROR_INFLATION, e.getMessage(), e);
} catch (Throwable e) {
// get the real cause of the exception.
Throwable t = e;
@@ -373,7 +378,7 @@
// log it
mParams.getLogger().error(t);
- return new SceneResult("Unknown error during inflation.", t);
+ return new SceneResult(SceneStatus.ERROR_INFLATION, t.getMessage(), t);
}
}
@@ -391,7 +396,7 @@
try {
long current = System.currentTimeMillis();
if (mViewRoot == null) {
- return new SceneResult("Layout has not been inflated!");
+ return new SceneResult(SceneStatus.ERROR_NOT_INFLATED);
}
// measure the views
int w_spec, h_spec;
@@ -487,7 +492,7 @@
// log it
mParams.getLogger().error(t);
- return new SceneResult("Unknown error during rendering.", t);
+ return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
}
}
@@ -530,12 +535,74 @@
return SceneResult.SUCCESS;
}
} catch (Exception e) {
- e.printStackTrace();
- return new SceneResult("", e);
+ // get the real cause of the exception.
+ Throwable t = e;
+ while (t.getCause() != null) {
+ t = t.getCause();
+ }
+
+ return new SceneResult(SceneStatus.ERROR_UNKNOWN, t.getMessage(), t);
}
}
- return new SceneResult("Failed to find animation");
+ return new SceneResult(SceneStatus.ERROR_ANIM_NOT_FOUND);
+ }
+
+ public SceneResult insertChild(ViewGroup parentView, IXmlPullParser childXml,
+ View beforeSibling, IAnimationListener listener) {
+ checkLock();
+
+ int index = parentView.indexOfChild(beforeSibling);
+ if (beforeSibling != null && index == -1) {
+ throw new IllegalArgumentException("beforeSibling not in parentView");
+ }
+
+ // create a block parser for the XML
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, mContext,
+ false /* platformResourceFlag */);
+
+ // inflate the child without adding it to the root since we want to control where it'll
+ // get added. We do pass the parentView however to ensure that the layoutParams will
+ // be created correctly.
+ View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/);
+
+ // add it to the parentView in the correct location
+ parentView.addView(child, index);
+
+ return render();
+ }
+
+ public SceneResult moveChild(ViewGroup parentView, View childView, View beforeSibling,
+ IAnimationListener listener) {
+ checkLock();
+
+ int index = parentView.indexOfChild(beforeSibling);
+ if (beforeSibling != null && index == -1) {
+ throw new IllegalArgumentException("beforeSibling not in parentView");
+ }
+
+ ViewParent parent = childView.getParent();
+ if (parent instanceof ViewGroup) {
+ ViewGroup parentGroup = (ViewGroup) parent;
+ parentGroup.removeView(childView);
+ }
+
+ // add it to the parentView in the correct location
+ parentView.addView(childView, index);
+
+ return render();
+ }
+
+ public SceneResult removeChild(View childView, IAnimationListener listener) {
+ checkLock();
+
+ ViewParent parent = childView.getParent();
+ if (parent instanceof ViewGroup) {
+ ViewGroup parentGroup = (ViewGroup) parent;
+ parentGroup.removeView(childView);
+ }
+
+ return render();
}
/**
@@ -915,4 +982,12 @@
public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
return mContext.getDefaultPropMap(viewObject);
}
+
+ public void setScene(LayoutScene scene) {
+ mScene = scene;
+ }
+
+ public LayoutScene getScene() {
+ return mScene;
+ }
}