diff options
170 files changed, 3375 insertions, 1423 deletions
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 @@ public final class Pm { 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 @@ public abstract class ActionBar { * @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 @@ public abstract class ActionBar { * 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 @@ public abstract class ActionBar { * @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 @@ public abstract class ActionBar { */ @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 class ActionBar { 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 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 NavigationCallback { + public interface OnNavigationListener { /** * This method is called whenever a navigation item in your action bar * is selected. @@ -547,6 +562,21 @@ public abstract class ActionBar { } /** + * 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.Build; 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.FileDescriptor; 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 @@ public class Activity extends ContextThemeWrapper * @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 @@ public class Activity extends ContextThemeWrapper * @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 @@ public class Activity extends ContextThemeWrapper return true; } return mFragments.dispatchContextItemSelected(item); - + default: return false; } @@ -2417,6 +2420,10 @@ public class Activity extends ContextThemeWrapper case Window.FEATURE_CONTEXT_MENU: onContextMenuClosed(menu); break; + + case Window.FEATURE_ACTION_BAR: + mActionBar.dispatchMenuVisibilityChanged(false); + break; } } @@ -3502,6 +3509,22 @@ public class Activity extends ContextThemeWrapper } /** + * 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 @@ public class Activity extends ContextThemeWrapper 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 @@ public final class ActivityThread { boolean startsNotResumed; boolean isForward; + int pendingConfigChanges; + boolean onlyLocalRequest; + + View mPendingRemoveWindow; + WindowManager mPendingRemoveWindowManager; ActivityClientRecord() { parent = null; @@ -444,19 +449,8 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } 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 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } } - 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 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } 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 @@ public final class ActivityThread { } } - 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 @@ public final class ActivityThread { ActivityClientRecord r = mRelaunchingActivities.get(i); if (r.token == token) { tmp = r; + configChanges |= tmp.pendingConfigChanges; mRelaunchingActivities.remove(i); i--; N--; @@ -2799,6 +2882,10 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } 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 @@ public class Dialog implements DialogInterface, Window.Callback, * @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 @@ public class Dialog implements DialogInterface, Window.Callback, * @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 @@ public class Camera { 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 @@ public class Camera { /** * 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 @@ public class Camera { } /** + * 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 @@ public final class Downloads { "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.content.ContentUris; 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 @@ public final class Ptp /** * 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 @@ public final class Ptp } /** - * 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 @@ public final class Ptp } /** - * 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 final class Ptp 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 final class Ptp 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 @@ public final class Ptp /** * 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 @@ public class DragEvent implements Parcelable { float mX, mY; ClipDescription mClipDescription; ClipData mClipData; + Object mLocalState; boolean mDragResult; private DragEvent mNext; @@ -139,11 +140,11 @@ public static final int ACTION_DRAG_EXITED = 6; } 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 @@ public static final int ACTION_DRAG_EXITED = 6; /** @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 @@ public static final int ACTION_DRAG_EXITED = 6; } /** + * 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 @@ public static final int ACTION_DRAG_EXITED = 6; 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility 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 @@ public class ViewConfiguration { /** * 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 @@ public final class ViewRoot extends Handler implements ViewParent, /* Drag/drop */ ClipDescription mDragDescription; View mCurrentDragView; + Object mLocalDragState; final PointF mDragPoint = new PointF(); final PointF mLastTouchPoint = new PointF(); @@ -585,6 +586,9 @@ public final class ViewRoot extends Handler implements ViewParent, dirty.inset(-1, -1); } } + if (!mDirty.isEmpty()) { + mAttachInfo.mIgnoreDirtyState = true; + } mDirty.union(dirty); if (!mWillDrawSoon) { scheduleTraversals(); @@ -2680,6 +2684,10 @@ public final class ViewRoot extends Handler implements ViewParent, } /* 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 @@ public final class ViewRoot extends Handler implements ViewParent, } } - // 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 @@ public final class ViewRoot extends Handler implements ViewParent, 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 @@ public final class ViewRoot extends Handler implements ViewParent, } 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 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, private Resources mResources; private boolean mMatchesFound; private int mNumberOfMatches; - private View mTitleBar; private ActionMode mActionMode; FindActionModeCallback(Context context) { @@ -62,8 +61,6 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, mResources = context.getResources(); } - void setTitleBar(View v) { mTitleBar = v; } - void finish() { mActionMode.finish(); } @@ -174,7 +171,6 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, @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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout * @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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout } 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 com.android.internal.R; import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; @@ -57,6 +59,23 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { } } - + + 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class LinearLayout extends ViewGroup { 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 @@ public class ListView extends AbsListView { } mDivider = divider; mDividerIsOpaque = divider == null || divider.getOpacity() == PixelFormat.OPAQUE; - requestLayoutIfNecessary(); + requestLayout(); + invalidate(); } /** @@ -3214,7 +3215,8 @@ public class ListView extends AbsListView { */ 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 @@ import android.view.animation.AnimationUtils; * {@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 boolean mFlywheel; + private final Interpolator mInterpolator; - 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 final boolean mFlywheel; 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; - } + /** + * Creates an OverScroller with a viscous fluid scroll interpolator. + * @param context + */ + public OverScroller(Context context) { + this(context, null); + } - { - 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 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); } - public OverScroller(Context context) { - this(context, null, 0.f, 0.f, true); + /** + * 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 @@ public class OverScroller { * 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 @@ public class OverScroller { * 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 class OverScroller { 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 @@ public class OverScroller { 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 class OverScroller { */ 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 @@ public class OverScroller { 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; - private static final int TO_EDGE = 0; - private static final int TO_BOUNDARY = 1; - private static final int TO_BOUNCE = 2; + // 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; - // The allowed overshot distance before boundary is reached. - private int mOver; + // 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; // 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 @@ public class OverScroller { /* * 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 @@ public class OverScroller { 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 @@ public class OverScroller { 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 @@ public class OverScroller { 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 @@ public class OverScroller { } } + 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 @@ public class OverScroller { 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 @@ public class OverScroller { // 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 @@ public class OverScroller { } 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.FloatMath; 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (mSelectAllOnFocus) { - Selection.setSelection((Spannable) mText, 0, mText.length()); + selectAll(); } mTouchFocusSelected = true; @@ -7401,10 +7403,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * 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. + * + * 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. + */ + public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) { + mCustomSelectionActionModeCallback = actionModeCallback; + } + + /** + * Retrieves the value set in {@link #setCustomSelectionActionModeCallback}. Default is null. * - * @return A callback instance that will be used to start selection mode, or null if selection - * mode is not available. + * @return The current custom selection callback. */ - private ActionMode.Callback getActionModeCallback() { - if (canSelectText()) { - return new SelectionActionModeCallback(); - } - return null; + public ActionMode.Callback getCustomSelectionActionModeCallback() { + return mCustomSelectionActionModeCallback; } /** @@ -7884,7 +7908,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public void onDestroyActionMode(ActionMode mode) { + if (mCustomSelectionActionModeCallback != null) { + mCustomSelectionActionModeCallback.onDestroyActionMode(mode); + } Selection.setSelection((Spannable) mText, getSelectionStart()); hideSelectionModifierCursorController(); mSelectionActionMode = null; @@ -8744,7 +8785,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + 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 @@ public class ActionBarImpl extends ActionBar { 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 @@ public class ActionBarImpl extends ActionBar { 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 @@ public class ActionBarImpl extends ActionBar { 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 class ActionBarImpl extends ActionBar { public void onMenuModeChange(MenuBuilder menu) { invalidate(); - mUpperContextView.showOverflowMenu(); + mUpperContextView.openOverflowMenu(); } } @@ -627,7 +651,7 @@ public class ActionBarImpl extends ActionBar { } @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 @@ public class AlertController { 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 @@ public class AlertController { 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 @@ public class AlertController { 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 @@ public class AlertController { 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 @@ public class AlertController { @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 @@ public class AlertController { } } 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 c930c57..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.io.PrintStream; 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 @@ public class SamplingProfilerIntegration { 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 @@ public class SamplingProfilerIntegration { } 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 @@ public class SamplingProfilerIntegration { 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 @@ public class SamplingProfilerIntegration { if (!enabled) { return; } - writeSnapshot("zygote", null); + writeSnapshotFile("zygote", null); INSTANCE.shutdown(); INSTANCE = null; } @@ -148,7 +145,7 @@ public class SamplingProfilerIntegration { /** * 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 @@ public class SamplingProfilerIntegration { */ 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { * @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 @@ public class AsyncChannel { 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { * @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 @@ public class AsyncChannel { 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { * * 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 @@ public class AsyncChannel { /** * 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 @@ public class AsyncChannel { * * @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 @@ public class AsyncChannel { * 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 class StandaloneActionMode extends ActionMode implements MenuBuilder.Call 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } }; + 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } } + @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 class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } 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 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo 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 @@ import java.lang.ref.WeakReference; * @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 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On 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 class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On 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 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On 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 @@ public class ActionBarContextView extends ViewGroup { 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.ActionMenuView; 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 @@ public class ActionBarView extends ViewGroup { private ActionMenuItem mLogoNavItem; private SpinnerAdapter mSpinnerAdapter; - private NavigationCallback mCallback; + private OnNavigationListener mCallback; private final AdapterView.OnItemSelectedListener mNavItemSelectedListener = new AdapterView.OnItemSelectedListener() { @@ -243,7 +243,7 @@ public class ActionBarView extends ViewGroup { return null; } - public void setCallback(NavigationCallback callback) { + public void setCallback(OnNavigationListener callback) { mCallback = callback; } @@ -269,6 +269,12 @@ public class ActionBarView extends ViewGroup { return false; } + public void openOverflowMenu() { + if (mMenuView != null) { + mMenuView.openOverflowMenu(); + } + } + public void postShowOverflowMenu() { post(new Runnable() { public void run() { @@ -291,6 +297,13 @@ public class ActionBarView extends ViewGroup { 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 Binary files differnew file mode 100644 index 0000000..8bb4048 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..fdd3ee7 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 4275da0..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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differnew file mode 100644 index 0000000..0ce5d13 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_focused_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..945516e --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png b/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png Binary files differnew file mode 100644 index 0000000..2993b44 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_longpress_holo.9.png 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 Binary files differnew file mode 100644 index 0000000..33e6dc8 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..eb0d90f --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differnew file mode 100644 index 0000000..4a98e57 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..5cf6bf3 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png b/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png Binary files differnew file mode 100644 index 0000000..4aad237 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_pressed_holo.9.png 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 Binary files differnew file mode 100644 index 0000000..8bb4048 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..fdd3ee7 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differnew file mode 100644 index 0000000..0ce5d13 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_focused_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..945516e --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png b/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png Binary files differnew file mode 100644 index 0000000..2993b44 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_longpress_holo.9.png 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 Binary files differnew file mode 100644 index 0000000..33e6dc8 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..eb0d90f --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differindex 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 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 Binary files differnew file mode 100644 index 0000000..4a98e57 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png 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 Binary files differnew file mode 100644 index 0000000..5cf6bf3 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png b/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png Binary files differnew file mode 100644 index 0000000..4aad237 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_pressed_holo.9.png diff --git a/core/res/res/drawable/edit_text_holo_dark.xml b/core/res/res/drawable/edit_text_holo_dark.xml index 63ccd1d..29a5150 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 f65f585..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 @@ public class UriTest extends TestCase { 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 c3d3482..44d75c1 100644 --- a/docs/html/guide/topics/ui/actionbar.jd +++ b/docs/html/guide/topics/ui/actionbar.jd @@ -455,7 +455,7 @@ Action Bar.</p> <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 @@ android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}. 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 @@ defined as a resource looks like this:</p> </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 @@ mNavigationCallback = new NavigationCallback() { }; </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 @@ Android Market within a 14-day period ending on the data collection date noted b <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 @@ Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b, <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 @@ Android Market within a 14-day period ending on the date indicated on the x-axis <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" /> - -<p><em>Last historical dataset collected during two weeks ending on November 1, 2010</em></p> +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 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 @@ public class MediaScanner 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.provider.MediaStore.MediaColumns; import android.util.Log; import java.io.File; +import java.util.HashMap; /** * {@hide} @@ -48,6 +49,14 @@ public class MtpDatabase { 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 @@ public class MtpDatabase { 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 @@ public class MtpDatabase { case MtpConstants.FORMAT_PNG: case MtpConstants.FORMAT_BMP: return IMAGE_PROPERTIES; + case 0: + return ALL_PROPERTIES; default: return FILE_PROPERTIES; } @@ -415,324 +463,32 @@ public class MtpDatabase { }; } - 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); - } - } - - 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)); - } - } + 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); } - - 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 @@ public class MtpDatabase { 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 @@ package android.media; /** * 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 class MtpPropertyList { 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 @@ public class MtpPropertyList { 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 @@ public: 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 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, 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::resetDeviceProperty(MtpDeviceProperty property) { } 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 @@ android_media_MtpDatabase_finalize(JNIEnv *env, jobject thiz) } 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 @@ android_media_MtpDatabase_format_date_time(JNIEnv *env, jobject thiz, jlong seco // ---------------------------------------------------------------------------- -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 @@ int register_android_media_MtpDatabase(JNIEnv *env) 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 @@ int register_android_media_MtpDatabase(JNIEnv *env) 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 @@ status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) { 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 @@ status_t StagefrightRecorder::setParamMaxFileSizeBytes(int64_t bytes) { 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 @@ bool MPEG4Writer::exceedsFileSizeLimit() { 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 @@ public: 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 @@ MtpProperty::MtpProperty(MtpPropertyCode propCode, 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::doResetDevicePropValue() { 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..b0597c4 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..1eb7851 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 @@ public class ShirtPocket extends FrameLayout { 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 @@ public class TabletStatusBar extends StatusBar { // 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 @@ public class TabletStatusBar extends StatusBar { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private ContextMenuBuilder mContextMenu; private MenuDialogHelper mContextMenuHelper; + private ActionButtonSubmenu mActionButtonPopup; + private boolean mClosingActionMenu; private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; @@ -542,6 +544,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } + 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev 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 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev { if (AudioSystem::isBluetoothScoDevice(device)) { mScoDeviceAddress = ""; -#ifdef WITH_A2DP - if (mA2dpOutput != 0 && - mPhoneState != AudioSystem::MODE_NORMAL) { - mpClientInterface->restoreOutput(mA2dpOutput); - } -#endif } } } break; @@ -138,6 +126,7 @@ status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_dev if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) { closeA2dpOutputs(); } + checkA2dpSuspend(); #endif updateDeviceForStrategy(); setOutputDevice(mHardwareOutput, newDevice); @@ -280,14 +269,7 @@ void AudioPolicyManagerBase::setPhoneState(int state) 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 @@ void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSyst uint32_t newDevice = getNewDevice(mHardwareOutput, false); #ifdef WITH_A2DP checkOutputForAllStrategies(); + checkA2dpSuspend(); #endif updateDeviceForStrategy(); setOutputDevice(mHardwareOutput, newDevice); @@ -1025,8 +1008,10 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien #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 @@ status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices } 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 @@ status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput); } } + + mA2dpSuspended = false; + return NO_ERROR; } @@ -1369,6 +1346,7 @@ status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devi } } mA2dpDeviceAddress = ""; + mA2dpSuspended = false; return NO_ERROR; } @@ -1467,6 +1445,48 @@ void AudioPolicyManagerBase::checkOutputForAllStrategies() 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 @@ void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t // 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 @@ void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t // 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 @@ public class WifiService extends IWifiManager.Stub { 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub // 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 @@ public class WindowManagerService extends IWindowManager.Stub } 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 @@ public class WindowManagerService extends IWindowManager.Stub 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.IXmlPullParser; 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 @@ public final class Bridge extends LayoutBridge { 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 @@ public class BridgeLayoutScene extends LayoutScene { } @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 @@ public class AnimationThread extends Thread { 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.internal.util.XmlUtils; 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.DisplayMetrics; 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 @@ public class LayoutSceneImpl { private final SceneParams mParams; // scene state + private LayoutScene mScene; private BridgeContext mContext; private BridgeXmlBlockParser mBlockParser; private BridgeInflater mInflater; @@ -362,7 +367,7 @@ public class LayoutSceneImpl { 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 @@ public class LayoutSceneImpl { // 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 @@ public class LayoutSceneImpl { 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 @@ public class LayoutSceneImpl { // 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 @@ public class LayoutSceneImpl { 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 class LayoutSceneImpl { public Map<String, String> getDefaultViewPropertyValues(Object viewObject) { return mContext.getDefaultPropMap(viewObject); } + + public void setScene(LayoutScene scene) { + mScene = scene; + } + + public LayoutScene getScene() { + return mScene; + } } |